﻿/* !
** FireView - виджет для безопасной работы с консолью Firebug
** @version:
**   0.0.1
** @description:
**   Если в браузере не существует консоли Firebug, то виджет добавляет её "пустышку" для предотвращения ошибок
**   Если в браузер установлена консоль Firebug ниже версии 1.5, то виджет создаёт свойства-функции-пустышки в консоли для предотвращения ошибок
** @author:
**   Александр Кузнецов aka Regent(http://l-i-v-e.ru/)
** @license:
**   GNU General Public License version 3 - http://www.gnu.org/copyleft/gpl.html
** @home:
**   http://jsam-modx.net/
** @blog:
**   http://l-i-v-e.ru/
** @twitter:
**   http://twitter.com/vjRegent
*/
(
	function( window, top ){
		
		GetConsoleObject: {
			if( !window.console ){
				window.console = top.console && top.console.firebug ? top.console : {};
			}
		} // </GetConsoleObject
		
		DeclareVariables: {
			var
				names = [ 'log', 'debug', 'info', 'warn', 'error', 'assert', 'dir', 'dirxml', 'trace', 'group', 'groupCollapsed', 'groupEnd', 'time', 'timeEnd', 'profile', 'profileEnd', 'count' ],
				length = names.length,
				i = 0;
		} // </DeclareVariables
		
		CreateDummyFunctions: {
			for( ; i < length; i++ ){
				if( !window.console[ names[ i ] ] ){
					window.console[ names[ i ] ] = function(){};
				}
			}
		} // </CreateDummyFunctions
		
	}
)( window, top );

/* !
** jSam - JavaScript Admin-Manager
** @version:
**   0.1
** @description:
**   Инструментарий разработчика MODx для настройки внешнего вида административной панели с помощью JavaScript-правил
** @author:
**   Александр Кузнецов aka Regent(http://l-i-v-e.ru/)
** @license:
**   GNU General Public License version 3 - http://www.gnu.org/copyleft/gpl.html
** @home:
**   http://jsam-modx.net/
** @blog:
**   http://l-i-v-e.ru/
** @twitter:
**   http://twitter.com/vjRegent
*/
(
	function( window, document, $, undefined ){
		
		/*
		** Добавление к объекту String метода trim
		** Метод удаляет символы отступа(пример, RegExp: /\s/) вначале и в конце строки
		*/
		SetTrimFunction: {
			if( !String.prototype.trim ){
				var trimExpr = '[\\x09\\x0A-\\x0D\\x20\\xA0\\u1680\\u180E\\u2000-\\u200A\\u2028\\u2029\\u202F\\u205F\\u3000]+';
				trimExpr = new RegExp( '^' + trimExpr + '|' + trimExpr + '$', 'g' );
				String.prototype.trim = function(){
					return this.replace( trimExpr, '' );
				};
			}
		} // </SetTrimFunction
		
		/*
		** Плагин к библиотеке jQuery - foreach
		** Это аналог метода each, только ключевое слово this указывает на jQuery Object текущего элемента
		*/
		$.fn.foreach = function( fn ){
			for( var i = 0, length = this.length; i < length; i++ ){
				fn.call( this.eq( i ), i, this.get( i ) );
			}
			return this;
		};
		
		/*
		** Объявление переменных
		*/
		DeclareVariables: {
			var
				
				// Ссылки на часто используемые функции
				log, info, lang, foreach,
				
				// Быстрая ссылка на jQuery.extend
				extend = $.extend,
				
				// Быстрая ссылка на консоль Firebug
				console = window.console,
				
				_, jSam,
				
				// Сохранение предыдущих глобальных переменны _ и jSam
				__ = window._, _jSam = window.jSam,
				
				// jQuery-пустышка
				a = $(),
				
				url = ( window.jSamData || {} ).url;
			
		} // </DeclareVariables
		
		// Инициализация jSam
		top.jSam = top._ = window.jSam = window._ = jSam = _ = extend(
			
			/*
			** @name:
			**   jSam
			** @path:
			**   jSam
			** @description:
			**   Добавить функцию с jSam-правилами для исполнения во время полной загрузки фрейма
			** @type:
			**   Function
			** @api:
			**   jSam( fn );
			**   jSam( frameType, fn );
			** @param "frameType":
			**   Тип фрейма, в котором должны выполняться правила
			** @param "fn":
			**   Функция, выполняемая при загрузке фрейма. Функция содержит в себе jSam-правила
			** @returns:
			**   Object - jSam
			** @example:
			**   jSam(function( data, jQuery, log ){
			**     if( data.id == 5 )
			**       this.tab.hide();
			**   });
			*/
			function( frameType, fn ){
				if( arguments.length > 1 && _.isString( frameType ) && _.data.type == frameType && $.isFunction( fn ) ){
					_.fns.rules.push( fn );
				}
				else if( $.isFunction( frameType ) ){
					_.fns.rules.push( frameType );
				}
				return _;
			},
			{
				
				
				//********************************//
				//***** Статические свойства *****//
				//********************************//
				
				
				/*
				** @name:
				**   $
				** @path:
				**   jSam -> $
				** @description:
				**   Ссылка на jQuery
				** @type:
				**   Object
				*/
				'$': $,
				
				/*
				** @name:
				**   data
				** @path:
				**   jSam -> data
				** @description:
				**   Главный информационный объект
				** @type:
				**   Object
				*/
				data: extend(
					true,
					window.jSamData || {},
					{
						/*
						** @name:
						**   loadState
						** @path:
						**   jSam -> data -> loadState
						** @description:
						**   Статус загрузки фрейма
						** @type:
						**   Boolean
						*/
						loadState: false,
						
						/*
						** @name:
						**   rules
						** @path:
						**   jSam -> data -> rules
						** @description:
						**   Статус выполнения правил
						** @type:
						**   Boolean
						*/
						rules: false,
						
						/*
						** @name:
						**   isRules
						** @path:
						**   jSam -> data -> isRules
						** @description:
						**   Существуют ли функции правил для выполнения
						** @type:
						**   Boolean
						*/
						isRules: false,
						
						/*
						** @name:
						**   _lang
						** @path:
						**   jSam -> data -> _lang
						** @description:
						**   Массив русских фраз с переводом на язык административной панели
						** @type:
						**   Array
						*/
						_lang: {
							"jSam интегрирован во фрейм": {
								"english": "jSam integrated into the frame",
								"francais": "jSam intégré dans le cadre"
							},
							"Информация о фрейме": {
								"english": "Information frame",
								"francais": "Cadre de l'information"
							},
							"Тип фрейма": {
								"english": "Frame Type",
								"francais": "Type de trame"
							},
							"Ссылка": {
								"english": "Link",
								"francais": "Lien"
							},
							"ссылка": {
								"english": "link",
								"francais": "lien"
							},
							"Объект": {
								"english": "Object",
								"francais": "Objet"
							},
							"объект": {
								"english": "object",
								"francais": "objet"
							},
							"Фрейм": {
								"english": "Frame",
								"francais": "Cadre"
							},
							"Количество DOM-узлов фрейма": {
								"english": "Number of DOM-node frame",
								"francais": "Nombre de cadre DOM-noeud"
							},
							"Информация о версиях": {
								"english": "Version information",
								"francais": "Informations sur les versions"
							},
							"Данные документа": {
								"english": "Document data",
								"francais": "Les données du document"
							},
							"Данные фрейма": {
								"english": "Data frame",
								"francais": "Cadre de données"
							},
							"Время выполнения правил фрейма": {
								"english": "Time frame rules",
								"francais": "Calendrier des règles"
							},
							"Инструментарий для работы с фреймом": {
								"english": "Tools for working with the frame",
								"francais": "Outils pour travailler avec le cadre"
							}
						} // </_lang
						
					}
				), // </data
				
				/*
				** @name:
				**   fns
				** @path:
				**   jSam -> fns
				** @description:
				**   Объект массивов функций
				** @type:
				**   Object
				*/
				fns: {
					
					/*
					** @name:
					**   rules
					** @path:
					**   jSam -> fns -> rules
					** @description:
					**   Массив функций с правилами
					** @type:
					**   Array
					*/
					rules: [],
					
					/*
					** @name:
					**   exit
					** @path:
					**   jSam -> fns -> exit
					** @description:
					**   Массив функций, выполняемых при выходе со страницы или отправке формы
					** @type:
					**   Array
					*/
					exit: []
					
				}, // </fns
				
				
				//*******************//
				//***** Функции *****//
				//*******************//
				
				
				/*********************************/
				/***** Функции - инструменты *****/
				/*********************************/
				
				
				/*
				** @name:
				**   log
				** @path:
				**   jSam -> log
				** @api:
				**   jSam.log( message );
				** @description:
				**   Отправить простое сообщение в консоль
				** @type:
				**   Function
				** @param "message":
				**   Любой элемент
				** @returns:
				**   null
				** @example:
				**   jSam.log( 'abc' );
				**   jSam.log( 'winodw: ', window );
				*/
				log: log = function(){
					return console.log.apply( console, arguments );
				}, // </log
				
				/*
				** @name:
				**   info
				** @path:
				**   jSam -> info
				** @api:
				**   jSam.info( message );
				** @description:
				**   Отправить сообщение в консоль с иконкой информации
				** @type:
				**   Function
				** @param "message":
				**   Любой элемент
				** @returns:
				**   null
				** @example:
				**   jSam.info( 'Attention!' );
				**   jSam.info( 'jSam: ', jSam );
				*/
				info: info = function(){
					return console.info.apply( console, arguments );
				}, // </info
				
				/*
				** @name:
				**   getName
				** @path:
				**   jSam -> getName
				** @api:
				**   jSam.getName( element );
				** @description:
				**   Получить название элемента
				** @type:
				**   Function
				** @param "element":
				**   Любой элемент
				** @returns:
				**   String
				** @example:
				**   jSam.getName( {} );                                          // "Object"
				**   jSam.getName( window );                                      // "Window"
				**   jSam.getName( document.getElementsByTagName( 'a' )[ 0 ] );   // "HTMLAnchorElement"
				*/
				getName: (
					function( toStr ){
						return function( element ){
							return typeof element == 'undefined' ? 'Undefined' : element == null ? 'Null' : toStr.call( element ).replace( /^\[object\s*|\]$/g, '' );
						}
					}
				)( Object.prototype.toString ), // </getName
				
				/*
				** @name:
				**   getClass
				** @path:
				**   jSam -> getClass
				** @api:
				**   jSam.getClass( object );
				** @description:
				**   Получить имя класса объекта
				** @type:
				**   Function
				** @param "object":
				**   Object - объект
				** @returns:
				**   String or Boolean
				** @example:
				**   jSam.getClass( new(function MyClass(){}) );     // "MyClass"
				**   jSam.getClass( {} );                            // "Object"
				**   jSam.getClass( 53 );                            // false
				**   jSam.getClass( function MyFn(){} );             // false
				*/
				getClass: function( object ){
					if( _.getName( object ) == 'Object' ){
						var match = object.constructor.toString().match( /^\s*function\s*(\w+)\(\)/ );
						if( match && match.length == 2 ){
							return match[ 1 ];
						}
					}
					return false;
				}, // </getClass
				
				/*
				** @name:
				**   toArray
				** @path:
				**   jSam -> toArray
				** @api:
				**   jSam.toArray( element );
				** @description:
				**   Превратить элемент в элементарный массив
				** @type:
				**   Function
				** @param "element":
				**   Любой элемент
				** @returns:
				**   Array
				** @example:
				**   jSam.toArray( 54 );                            // [ 54 ]
				**   jSam.toArray( { 0:52, 1:85, length:2 } );      // [ 52, 85 ]
				**   jSam.toArray( { 0:52, 1:85 } );                // [ { 0:52, 1:85 } ]
				*/
				toArray: function( elem ){
					if( !_.isPrimitive( elem ) && _.isNumber( elem.length ) && elem.length > 0 ){
						for( var array = [], i = 0, len = elem.length; i < len; i++ ){
							array[ i ] = elem[ i ];
						}
						return array;
					}
					else if( arguments.length > 0 ){
						return [ elem ];
					}
					return [];
				}, // </toArray
				
				/*
				** @name:
				**   toInlineArray
				** @path:
				**   jSam -> toInlineArray
				** @api:
				**   jSam.toInlineArray( element );
				** @description:
				**   Превращение элемента и вложенных в него массивов в один массив
				** @type:
				**   Function
				** @param "element":
				**   Любой элемент
				** @returns:
				**   Array
				** @example:
				**   jSam.toInlineArray( [ 52, [ 42, 85, [ 'Str1' ], 'Str2', [ { 0:82, length:1 } ] ], {} ] );      // [ 52, 42, 85, "Str1", "Str2", 82, {} ]
				*/
				toInlineArray: function( element ){
					if( arguments.length == 0 ){
						return [];
					}
					if( !( !_.isPrimitive( element ) && element.hasOwnProperty( 'length' ) ) ){
						return [ element ];
					}
					for( var array = [], len = element.length, i = 0, el; i < len; i++ ){
						el = element[ i ];
						if( typeof el == 'object' && el != null && _.isNumber( el.length ) ){
							array = array.concat( _.toInlineArray( el ) );
						}
						else{
							array.push( el );
						}
					}
					return array;
				}, // </toInlineArray
				
				/*
				** @name:
				**   foreach
				** @path:
				**   jSam -> foreach
				** @api:
				**   jSam.foreach( obj, fn );
				** @description:
				**   Пройтись по порядку по свойствами объекта/массива
				** @type:
				**   Function
				** @param "obj":
				**   Любой объект или обычный массив
				** @param "fn":
				**   Функция, выполняемая при проходе каждого свойства
				** @returns:
				**   Object - переменная obj, переданная первым параметром
				** @example:
				**   jSam.foreach( { 'k':5, 'e':6 }, function( value, key, index ){} );
				**   jSam.foreach( [ 'low', 'pro' ], function( value, index ){} );
				*/
				foreach: foreach = function( obj, fn ){
					if( _.getName( fn ) != 'Function' || _.isPrimitive( obj ) ){
						return false;
					}
					var index = 0, key;
					for( key in obj ){
						if( obj.hasOwnProperty( key ) ){
							fn.call( obj, obj[ key ], key, index );
							index++;
						}
					}
					return obj;
				}, // </foreach
				
				/*
				** @name:
				**   call
				** @path:
				**   jSam -> call
				** @api:
				**   jSam.call( element, fn );
				** @description:
				**   Выполнить функцию, в контексте которой ссылка this указывает на переданный элемент
				** @type:
				**   Function
				** @param "element":
				**   Любой элемент
				** @param "fn":
				**   Function
				** @returns:
				**   Element
				** @example:
				**   jSam.call( {}, function(){ this.newProp = 58; } );
				*/
				call: function( element, fn ){
					var result = fn.call( element, element );
					return typeof result != 'undefined' ? result : element;
				}, // </call
				
				/*
				** @name:
				**   lang
				** @path:
				**   jSam -> lang
				** @api:
				**   jSam.lang( phrase );
				** @description:
				**   Перевести русскую фразу на язык административной панели
				** @type:
				**   Function
				** @param "phrase":
				**   String - фраза на русском языке
				** @returns:
				**   Object - переменная obj, переданная первым параметром
				** @example:
				**   jSam.lang( 'Чанк' );
				**   jSam.lang( 'Время выполнения правил' );
				*/
				lang: lang = function( phrase ){
					var _phrase = _.data._lang[ phrase ] || _.data._lang[ phrase.toLowerCase() ];
					return _phrase && _phrase[ data.lang ] || phrase;
				}, // </lang
				
				/*
				** @name:
				**   serialize
				** @path:
				**   jSam -> serialize
				** @api:
				**   jSam.serialize( val );
				** @description:
				**   Аналог PHP функции serialize. Генерирует из элемента значение, пригодное для хранения в строке
				** @type:
				**   Function
				** @param "val":
				**   Любой элемент
				** @returns:
				**   String
				** @example:
				**   jSam.serialize( "String 1" );                                  // 's:8:"String 1";'
				**   jSam.serialize( 523 );                                         // 'i:523;'
				**   jSam.serialize( 3.14 );                                        // 'd:3.14;'
				**   jSam.serialize( true );                                        // 'b:1;'
				**   jSam.serialize( null );                                        // 'N;'
				**   jSam.serialize( [] ); jSam.serialize( {} );                    // 'a:0:{}'
				**   jSam.serialize( [ 5, 'Str' ] );                                // 'a:2:{i:0;i:5;i:1;s:3:"Str";}'
				**   jSam.serialize( { a: 5, b: 'Str!', c: [], d: { j: 5 } } );     // 'a:4:{s:1:"a";i:5;s:1:"b";s:4:"Str!";s:1:"c";a:0:{}s:1:"d";a:1:{s:1:"j";i:5;}}'
				*/
				serialize: function( val ) {
					if( val == null ){
						return 'N;';
					}
					switch( typeof val ){
						case 'string':
							return 's:' + val.length + ':"' + val + '";';
						case 'number':
							return parseInt( val ) == val ? 'i:' + val + ';' : 'd:' + val + ';';
						case 'boolean':
							return val ? 'b:1;' : 'b:0;';
						case 'object':
							var props = '', length = 0, isArray = $.isArray( val ), expr = /^[0-9]+$/;
							foreach(
								val,
								function( v, key ){
									if( isArray && expr.test( key ) ){
										props += 'i:' + key + ';' + _.serialize( v );
									}
									else{
										props += 's:' + key.length + ':"' + key + '";' + _.serialize( v );
									}
									length++;
								}
							);
							return length == 0 ? 'a:0:{}' : 'a:' + length + ':{' + props + '}';
						default:
							return 'N;';
					}
				}, // </serialize
				
				/*
				** @name:
				**   unserialize
				** @path:
				**   jSam -> unserialize
				** @api:
				**   jSam.unserialize( val );
				** @description:
				**   Аналог PHP функции unserialize. Генерирует из валидной строки реальный объекты
				** @type:
				**   Function
				** @param "val":
				**   String - строка, результат функции serialize
				** @returns:
				**   String
				** @example:
				**   jSam.unserialize( 's:8:"String 1";' );                                                                  // "String 1"
				**   jSam.unserialize( 'i:523;' );                                                                           // 523
				**   jSam.unserialize( 'd:3.14;' );                                                                          // 3.14
				**   jSam.unserialize( 'b:1;' );                                                                             // true
				**   jSam.unserialize( 'N;' );                                                                               // null
				**   jSam.unserialize( 'a:0:{}' );                                                                           // []
				**   jSam.unserialize( 'a:2:{i:0;i:5;i:1;s:3:"Str";}' );                                                     // [ 5, 'Str' ]
				**   jSam.unserialize( 'a:4:{s:1:"a";i:5;s:1:"b";s:4:"Str!";s:1:"c";a:0:{}s:1:"d";a:1:{s:1:"j";i:5;}}' );    // { a: 5, b: 'Str!', c: [], d: { j: 5 } }
				*/
				unserialize: function( val, isLength ){
					if( !_.isString( val ) ){
						return val;
					}
					var
						type = val.charAt( 0 ),
						end = val.indexOf( ';' ),
						elem = val.substring( 0, end + 1 ),
						len = elem.length,
						temp,
						res = null;
					switch( type ){
						case 's':
							temp = parseInt( val.substr( 2, val.substring( 2 ).indexOf( ':' ) ) );
							elem = temp.toString().length;
							res = val.substr( 4 + elem, temp );
							len = 6 + elem + temp;
							break;
						case 'i':
						case 'd':
							res = parseFloat( elem.substring( 2, elem.length - 1 ) );
							break;
						case 'b':
							res = elem.charAt( 2 ) == '1' ? true : false;
							break;
						case 'a':
							var
								_char = '',
								key,
								lastIndex = -1,
								arrayLength = parseInt( val.substr( 2, val.substring( 2 ).indexOf( ':' ) ) ),
								obj = {},
								str,
								a;
							len = 4 + arrayLength.toString().length;
							str = val.substring( len );
							while( str ){
								_char = str.charAt( 0 );
								switch( _char ){
									case 'i':
										key = parseInt( str.substr( 2, str.substring( 2 ).indexOf( ':' ) ) );
										if( key >= lastIndex ){
											lastIndex = key;
										}
										a = 3 + key.toString().length;
										temp = _.unserialize( str.substring( a ), true );
										obj[ key ] = temp.res;
										str = str.substring( a + temp.len );
										len = len + a + temp.len;
										break;
									case 's':
										temp = _.unserialize( str.substring( 0, str.indexOf( ';' ) + 1 ), true );
										key = temp.res;
										len = len + temp.len;
										str = str.substring( temp.len );
										temp = _.unserialize( str, true );
										obj[ key ] = temp.res;
										str = str.substring( temp.len );
										len += temp.len;
										break;
									case '}':
										len++;
										str = '';
										break;
									default:
										str = '';
										break;
								}
							}
							if( $.isEmptyObject( obj ) ){
								res = [];
							}
							else{
							
								if( lastIndex != -1 ){
									var _arr = new Array( lastIndex );
									foreach(
										obj,
										function( v, key, index ){
											_arr[ key ] = v;
										}
									);
									res = _arr;
								}
								else{
									res = obj;
								}
								
							}
							
							break;
						case 'N':
							res = null;
							len = 2;
							break;
						default:
							res = null;
							len = val.length;
							break;
					}
					
					return isLength ? { res: res, len: len } : res;
				}, // </unserialize
				
				/*
				** @name:
				**   getUnique
				** @path:
				**   jSam -> getUnique
				** @description:
				**   Получить уникальный идентификатор
				** @type:
				**   Function
				** @api:
				**   jSam.getUnique();
				** @returns:
				**   Number
				** @example:
				**   jSam.getUnique();
				*/
				getUnique: (
					function( floor, random, date ){
						return function(){
							return floor( +new date * random() );
						};
					}
				)( Math.floor, Math.random, Date ), // </getUnique
				
				/*
				** @name:
				**   toDateFormat
				** @path:
				**   jSam -> toDateFormat
				** @description:
				**   Форматировать timestamp в формат, заданный в настройках системы
				** @type:
				**   Function
				** @api:
				**   jSam.toDateFormat( timestamp, dateOnly );
				** @param "timestamp":
				**   String - timestamp даты
				** @param "timestamp":
				**   Boolean - создавать только дату без время
				** @returns:
				**   String
				** @example:
				**   jSam.toDateFormat( 0 );                       // '01-01-1970 03:00:00'
				**   jSam.toDateFormat( 0, true );                 // '01-01-1970'
				**   jSam.toDateFormat( 1273324287000 );           // '08-05-2010 17:11:27'
				**   jSam.toDateFormat( 1273324200000, true );     // '08-05-2010'
				*/
				toDateFormat: function( timestamp, dateOnly ){
					var
						time = new Date( arguments.length == 0 ? 0 : parseInt( ( timestamp + '' ).trim() ) ),
						a = {
							'YYYY': time.getFullYear(),
							'mm': time.getMonth() + 1,
							'dd': time.getDate(),
							'H': time.getHours(),
							'M': time.getMinutes(),
							'S': time.getSeconds()
						};
					foreach(
						a,
						function( val, key ){
							a[ key ] = val < 10 ? '0' + val : val;
						}
					);
					return ( _.data.config[ 'datetime_format' ] + ( dateOnly != true ? ' H:M:S' : '' ) ).replace(
						/\w+/g,
						function( key ){
							return a[ key ] ? a[ key ] : '';
						}
					);
				}, // </toDateFormat
				
				/*
				** @name:
				**   toTimeStamp
				** @path:
				**   jSam -> toTimeStamp
				** @description:
				**   Преобразовать строку(форматированную дату) в timestamp. При этом формат даты определяется автоматически
				** @type:
				**   Function
				** @api:
				**   jSam.toTimeStamp( str );
				** @param "str":
				**   String - дата
				** @returns:
				**   Number
				** @example:
				**   jSam.toTimeStamp( '10-05-1980 05:20:10' );     // 326769610000
				**   jSam.toTimeStamp( '2005/05/27' );              // 111714840000
				**   jSam.toTimeStamp( '12/26/1989' );              // 630633600000
				**   jSam.toTimeStamp( '03-09-1992 02:00:00' );     // 715471200000
				*/
				toTimeStamp: function( str ){
					var
						date = new Date( 0 ),
						days;
					if( _.isString( str ) ){
						str = str.replace(
							/ ([0-9]{2}):([0-9]{2}):([0-9]{2})$/,
							function( time, hours, minutes, seconds ){
								date.setHours( hours );
								date.setMinutes( minutes );
								date.setSeconds( seconds );
								return '';
							}
						);
						if( days = str.match( /^([0-9]{2})-([0-9]{2})-([0-9]{4})$/ ) ){
							date.setFullYear( days[ 3 ] );
							date.setMonth( parseInt( days[ 2 ].replace( /^0/, '' ) ) - 1 )
							date.setDate( days[ 1 ] );
						}
						else if( days = str.match( /^([0-9]{4})\/([0-9]{2})\/([0-9]{2})$/ ) ){
							date.setFullYear( days[ 1 ] );
							date.setMonth( parseInt( days[ 2 ].replace( /^0/, '' ) ) - 1 )
							date.setDate( days[ 3 ] );
						}
						else if( days = str.match( /^([0-9]{2})\/([0-9]{2})\/([0-9]{4})$/ ) ){
							date.setFullYear( days[ 3 ] );
							date.setMonth( parseInt( days[ 1 ].replace( /^0/, '' ) ) - 1 )
							date.setDate( days[ 2 ] );
						}
					}
					return date.getTime();
				}, // </toTimeStamp
				
				
				/****************************/
				/***** Функции проверки *****/
				/****************************/
				
				
				/*
				** @name:
				**   isString
				** @path:
				**   jSam -> isString
				** @api:
				**   jSam.isString( element );
				** @description:
				**   Проверить, является ли элемент строкой
				** @type:
				**   Function
				** @param "element":
				**   Любой элемент
				** @returns:
				**   Boolean
				** @example:
				**   jSam.isString( 'abc' );                  // true
				**   jSam.isString( new String( 'abc' ) );    // true
				**   jSam.isString( new Number( 125 ) );      // false
				**   jSam.isString( 58 );                     // false
				**   jSam.isString( { 'k':5 } );              // false
				*/
				isString: function( element ){
					return _.getName( element ) == 'String';
				}, // </isString
				
				/*
				** @name:
				**   isNumber
				** @path:
				**   jSam -> isNumber
				** @api:
				**   jSam.isNumber( element );
				** @description:
				**   Проверить, является ли элемент числом
				** @type:
				**   Function
				** @param "element":
				**   Любой элемент
				** @returns:
				**   Boolean
				** @example:
				**   jSam.isNumber( 'abc' );                  // false
				**   jSam.isNumber( new Number( 'abc' ) );    // false
				**   jSam.isNumber( new Number( 125 ) );      // true
				**   jSam.isNumber( 58 );                     // true
				**   jSam.isNumber( { 'k':5 } );              // false
				*/
				isNumber: function( element ){
					return _.getName( element ) == 'Number';
				}, // </isNumber
				
				/*
				** @name:
				**   isNumberOrString
				** @path:
				**   jSam -> isNumberOrString
				** @api:
				**   jSam.isNumberOrString( element );
				** @description:
				**   Проверить, является ли элемент числом или строкой
				** @type:
				**   Function
				** @param "element":
				**   Любой элемент
				** @returns:
				**   Boolean
				** @example:
				**   jSam.isNumberOrString( 'abc' );                  // true
				**   jSam.isNumberOrString( new String( 'abc' ) );    // true
				**   jSam.isNumberOrString( 58 );                     // true
				**   jSam.isNumberOrString( { 'k':5 } );              // false
				**   jSam.isNumberOrString( new Number( 72 ) );       // true
				*/
				isNumberOrString: function( element ){
					var name = _.getName( element );
					return name == 'Number' || name == 'String';
				}, // </isNumberOrString
				
				/*
				** @name:
				**   isPrimitive
				** @path:
				**   jSam -> isPrimitive
				** @api:
				**   jSam.isPrimitive( element );
				** @description:
				**   Проверить, является ли переданный элемент примитивом, т. е. таким элементом, которому нельзя назначать свойства
				** @type:
				**   Function
				** @param "element":
				**   Любой элемент
				** @returns:
				**   Boolean
				** @example:
				**   jSam.isPrimitive( 'abc' );                         // true
				**   jSam.isPrimitive( 48 );                            // true
				**   jSam.isPrimitive( window.UndefinedVariable );      // true
				**   jSam.isPrimitive( null );                          // true
				**   jSam.isPrimitive( NaN );                           // true
				**   jSam.isPrimitive( true );                          // true
				**   jSam.isPrimitive( {} );                            // false
				**   jSam.isPrimitive( new Date() );                    // false
				**   jSam.isPrimitive( function(){} );                  // false
				**   jSam.isPrimitive( new String( 'low' ) );           // false
				*/
				isPrimitive: function( element ){
					var type = typeof element;
					return element == null || ( type != 'object' && type != 'function' );
				}, // </isPrimitive
				
				/*
				** @name:
				**   is$
				** @path:
				**   jSam -> is$
				** @api:
				**   jSam.is$( element );
				** @description:
				**   Проверить, является ли переданный элемент объектом jQuery
				** @type:
				**   Function
				** @param "element":
				**   Любой элемент
				** @returns:
				**   Boolean
				** @example:
				**   jSam.is$( $( 'a' ) );                         // true
				**   jSam.is$( 'abc' );                            // false
				*/
				is$: function( element ){
					return _.getName( element ) == 'Object' && _.getName( element.find ) == 'Function' && _.getName( element.jquery ) == 'String';
				}, // </is$
				
				/*
				** @name:
				**   isDOM
				** @path:
				**   jSam -> isDOM
				** @api:
				**   jSam.isDOM( element );
				** @description:
				**   Проверить, является ли переданный элемент DOM-узлом
				** @type:
				**   Function
				** @param "element":
				**   Любой элемент
				** @returns:
				**   Boolean
				** @example:
				**   jSam.isDOM( $( 'a' )[ 0 ] );                                      // true
				**   jSam.isDOM( document.getElementsByTagName( 'script' )[ 0 ] );     // true
				**   jSam.isDOM( document.createElement( 'script' ) );                 // true
				**   jSam.isDOM( document.body );                                      // true
				**   jSam.isDOM( {} );                                                 // false
				**   jSam.isDOM( window );                                             // false
				*/
				isDOM: function( element ){
					var name = _.getName( element );
					return typeof element == 'object' && name != 'Object' && name.substr( 0, 4 ) == 'HTML';
				}, // </isDOM
				
				/*
				** @name:
				**   isAttribute
				** @path:
				**   jSam -> isAttribute
				** @api:
				**   jSam.isAttribute( element, name );
				** @description:
				**   Проверить, присутствует ли в DOM-узле атрибут
				** @type:
				**   Function
				** @param "element":
				**   DOM node
				** @param "name":
				**   String - имя атрибута
				** @returns:
				**   Boolean
				** @example:
				**   jSam.isDOM( $( 'a' ).get( 0 ), 'attrname' );
				**   jSam.isDOM( $( 'div' ).get( 0 ), 'style' );
				*/
				isAttribute: function( element, name ){
					return element.hasAttribute ? element.hasAttribute( name ) : element.getAttribute ? element.getAttribute( name ) != null : false;
				},
				
				/*********************************************************/
				/***** Функции, взаимодействующие с UI или jSam.data *****/
				/*********************************************************/
				
				
				/*
				** @name:
				**   getFrameInfo
				** @path:
				**   jSam -> getFrameInfo
				** @api:
				**   jSam.getFrameInfo();
				** @description:
				**   Получить информацию объектом из формы mutate
				** @type:
				**   Function
				** @returns:
				**   Object
				*/
				getFrameInfo: function(){
					var
						obj = {},
						expr = /\[\]$/,
						isNumber = /^(?:-?)[0-9]+(?:\.[0-9]+)?$/;
					_.form
						.find( 'input, textarea, select' )
						.foreach(
							function( i, elem ){
								var
									name = elem.name,
									val = this.val();
								if( !( name && name != '' ) ){
									return;
								}
								if( isNumber.test( val ) ){
									val = parseFloat( val );
								}
								if( ( this.type == 'checkbox' || this.type == 'radio' ) && !this.checked ){
									return;
								}
								if( expr.test( name ) ){
									name = name.substring( 0, name.length - 2 );
								}
								if( obj.hasOwnProperty( name ) ){
									if( $.isArray( obj[ name ] ) ){
										obj[ name ].push( val );
									}
									else{
										obj[ name ] = [ obj[ name ], val ];
									}
								}
								else{
									obj[ name ] = val;
								}
							}
						);
					return obj;
				}, // </getFrameInfo
				
				/*
				** @name:
				**   getParents
				** @path:
				**   jSam -> getParents
				** @api:
				**   jSam.getParents( documentID );
				** @description:
				**   Получить массив родителей ресурса
				** @type:
				**   Function
				** @param "documentID":
				**   ID ресурса
				** @returns:
				**   Array - массив родителей
				** @example:
				**   jSam.getParents( 68 );
				*/
				getParents: function( documentID ){
					var array = [];
					while( _.data.parentMap[ documentID ] ){
						documentID = _.data.parentMap[ documentID ];
						array.push( documentID );
					}
					return array;
				}, // </getParents
				
				/*
				** @name:
				**   getDocumentLevel
				** @path:
				**   jSam -> getDocumentLevel
				** @api:
				**   jSam.getDocumentLevel( documentID );
				** @description:
				**   Получить уровень вложенности ресурса
				** @type:
				**   Function
				** @param "documentID":
				**   ID ресурса, уровень вложенности которого нужно получить
				** @returns:
				**   Number
				** @example:
				**   jSam.getDocumentLevel( 68 );
				*/
				getDocumentLevel: function( documentID ){
					return _.getParents( documentID ).length;
				}, // </getDOcumentLevel
				
				/*
				** @name:
				**   isDocument
				** @path:
				**   jSam -> isDocument
				** @api:
				**   jSam.isDocument( documentID );
				** @description:
				**   Проверить, является ли документ реально созданным
				** @type:
				**   Function
				** @param "documentID":
				**   ID ресурса
				** @returns:
				**   Boolean
				** @example:
				**   jSam.isDocument( 563 );
				*/
				isDocument: function( documentID ){
					return _.data.parentMap.hasOwnProperty( documentID );
				}, // </isDocument
				
				/*
				** @name:
				**   isParent
				** @path:
				**   jSam -> isParent
				** @api:
				**   jSam.isParent( documentID, parentID );
				** @description:
				**   Проверить, входит ли ресурс parentID в цепочку родителей ресурса documentID
				** @type:
				**   Function
				** @param "documentID":
				**   ID ресурса
				** @param "parentID":
				**   ID ресурса-родителя
				** @returns:
				**   Boolean
				** @example:
				**   jSam.isParent( 5, 84 );
				*/
				isParent: function( documentID, parentID ){
					return $.inArray( parentID, _.getParents( documentID ) ) !== -1;
				}, // </isParent
				
				/*
				** @name:
				**   createWebElement
				** @path:
				**   jSam -> createWebElement
				** @description:
				**   Создать web-элемент
				** @type:
				**   Function
				** @api:
				**   jSam.createWebElement( type, box, options );
				** @param "type":
				**   String - тип web-элемента
				** @param "box":
				**   String - название контейнера DOM-узла web-элемента
				**   DOM node - DOM-узел - контейнер web-элемента
				**   jQuery Object - DOM-узел - контейнер web-элемента
				**   DocumentFragment - DOM-узел - контейнер web-элемента
				**   Любое другое значение - функция автоматически создаёт дом узел HTMLTableCellElement
				** @param "options":
				**   Объект опций web-элемента:
				**   {
				**     help    : String,       // Всплывающая подсказка(ToolTip)
				**     attr    : Object,       // Атрибуты web-элемента
				**     value   : Mixed,        // Значение web-элемента
				**     values  : Mixed,        // Возможные значения web-элемента
				**     dirty   : Boolean,      // Обработчик событие на правку элемента - добавление предупреждения при выходе со страницы
				**     etc     : Mixed         // Различные другие опции для конкретного web-элемента
				**   }
				** @returns:
				**   jQuery Object - web-элемент
				** @example:
				**   jSam.createWebElement( 'text' );
				**   jSam.createWebElement( 'text', null );
				**   jSam.createWebElement( 'text', document.createDocumentFragment() );
				**   jSam.createWebElement( 'text', $( '[name="longtitle"]' ).parent() );
				**   jSam.createWebElement( 'text', $( '[name="longtitle"]' ).parent(), { attr: { name:'longtitle' } } )
				**   jSam.createWebElement( 'text', $( '[name="longtitle"]' ).parent(), { attr: { name:'newName', style:'color:green;width:100px;' } } );
				**   jSam.createWebElement( 'text', $( '[name="longtitle"]' ).parent(), { help: 'Text Tips<br><b>... text ...</b>' } );
				**   jSam.createWebElement( 'text', $( '[name="longtitle"]' ).parent(), { dirty: false } );
				**   jSam.createWebElement( 'text', $( '[name="longtitle"]' ).parent(), { value: 'New value!!!' } );
				**   jSam.createWebElement( 'textarea', $( '[name="longtitle"]' ).parent(), { value: "Multiline value\nMultiline value\nMultiline value" } );
				**   jSam.createWebElement( 'miniarea', $( '[name="longtitle"]' ).parent(), { help: "Расширенный заголовок", value: "\tMultiline\n\tvalue" } );
				**   jSam.createWebElement( 'menubox', $( '[name="longtitle"]' ).parent(), { multiple: true, size: 3, values: { 'AAA-AAA': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5 } } );
				**   jSam.createWebElement( 'miniarea', $( 'body' ) );
				**   jSam.createWebElement( 'number', document.getElementsByTagName( 'body' )[ 0 ] );
				**   jSam.createWebElement( 'colorpicker', $( 'body' ), { name:'abc', attr:{ style:'color:red;width:225px;' } } );
				**   jSam.createWebElement( 'date' );
				*/
				createWebElement: function( type, box, options ){
					CreateOptions:{
						options = extend(
							true,
							{
								attr: {
									name: 'webElement-' + _.getUnique()
								}
							},
							options || {}
						);
						CreateDirty: {
							if( options.dirty != false ){
								options.attr.onchange = 'window.documentDirty = true;' + ( options.attr.onchange || '' );
							}
						} // </CreateDirty
					} // </CreateOptions
					CreateBox: {
						if( _.isString( box ) ){
							box = $( '<' + box + '/>' );
						}
						if( _.isDOM( box ) || _.getName( box ) == "DocumentFragment" ){
							box = $( box );
						}
						if( _.is$( box ) ){
							box.empty();
						}
						else{
							box = $( '<div/>' );
						}
					} // </CreateBox
					WebElement: {
						var api = _.webElements[ type ];
						if( api ){
							CreateWebElement: {
								api.create && api.create( box, options );
							} // </CreateWebElement
							SetValue: {
								options.hasOwnProperty( 'value' ) && api.val && api.val( box, options.value );
							} // </SetValue
						}
					} // </WebElement
					CreateToolTip: {
						if( _.isNumberOrString( options.help ) ){
							box.html() && box.append( '&nbsp;&nbsp;&nbsp;' );
							box.append( _.ui.help( options.help ) );
						}
					} // </CreateToolTip
					return box;
				},
				
				/*
				** @name:
				**   detectWebElement
				** @path:
				**   jSam -> detectWebElement
				** @description:
				**   Определить тип тип webElement`a
				** @type:
				**   Function
				** @api:
				**   jSam.detectWebElement( box );
				** @param "box":
				**   jQuery Object - DOM-узел - контейнер web-элемента
				** @returns:
				**   String - тип webElement`a
				** @example:
				**   jSam.detectWebElement( $( '#node' ) );
				*/
				detectWebElement: function( box ){
					var
						type = 'noname',
						temp = box.data( 'webElement' );
					if( box.length ){
						if( temp ){
							type = _.isString( temp ) ? temp : temp.type;
						}
						else{
							for( var list = _.webElementList, i = list.length - 1, api; i >= 0; i-- ){
								if( !temp && ( api = _.webElements[ list[ i ] ] ) && api.is && api.is( box ) ){
									temp = list[ i ];
								}
							}
							if( temp ){
								type = temp;
							}
							box.data( 'webElement', { type: type } );
						}
					}
					return type;
				},
				
				/*
				** @name:
				**   createEditor
				** @path:
				**   jSam -> createEditor
				** @description:
				**   Создать визуальный редактор
				** @type:
				**   Function
				** @api:
				**   jSam.createEditor( textarea, type, options );
				** @param "textarea":
				**   String - атрибут ID DOM-узла
				**   DOM node - DOM-узел
				**   jQuery Object - DOM-узел
				** @param "type":
				**   String - тип визуального редактора из возможных
				** @param "options":
				**   Объект опций визуального редактора
				** @returns:
				**   jQuery Object
				** @example:
				**   jSam.createEditor( $( '[name="longtitle"]' ) );
				**   jSam.createEditor( $( '[name="introtext"]' ), 'tinyMCE' );
				**   jSam.createEditor( $( '[name="introtext"]' ), 'CKEditor' );
				**   jSam.createEditor( $( '[name="description"]' ), 'tinyMCE', { width:'307px', height: '150px',  theme: 'simple' } );
				**   jSam.createEditor( $( '[name="description"]' ), 'CKEditor', { width:'294px', height: '150px',  toolbar: 'Simple' } );
				**   jSam.createEditor( $( '[name="introtext"]' ), 'CKEditor', { toolbar: 'MODx', width: '468px', resize_enabled: false, toolbarCanCollapse: false } );
				**   jSam.createEditor( $( '#ta' ), 'CKEditor', { toolbar: 'Full' } );
				*/
				createEditor: function( textarea, type, options ){
					SetVariables: {
						var
							editorType = _.editors[ type = ( type || '' ).toLowerCase() ] ? type : _.data.config[ 'which_editor' ].toLowerCase(),
							api = _.editors[ editorType ],
							uid = 'element-' + _.getUnique(),
							id;
					} // </SetVariables
					TextareaManager: {
						if( _.isString( textarea ) ){
							textarea = $( '#' + textarea );
						}
						else if( _.isDOM( textarea ) ){
							textarea = $( textarea );
						}
						else if( !_.is$( textarea ) ){
							textarea = $( '<textarea/>' );
						}
						if( textarea.is( ':text' ) ){
							textarea.replaceWith(
								textarea = $( '<textarea/>' )
									.val( textarea.val() )
									.attr( 'name', textarea.attr( 'name' ) )
									.attr( 'id', textarea.attr( 'id' ) )
							);
						}
						if( !textarea.attr( 'id' ) ){
							textarea.attr( 'id', uid );
						}
						id = textarea.attr( 'id' );
					} // </TextareaManager
					CreateEditor: {
						if( !api || !api.init || ( api.hasOwnProperty( 'object' ) ? !window[ api.object ] : false ) ){
							break CreateEditor;
						} // </if
						options = extend( api.options || {}, options || {} );
						if( _.data.isRules ){
							textarea.removeData( '_editor' );
							api.init( textarea.get( 0 ), options );
							if( options.hasOwnProperty( 'value' ) && api.val ){
								api.val( textarea, options.value );
							}
						} // </if( _.data.isRules ){
						else{
							textarea.data(
								'_editor',
								{
									type: editorType,
									options: options
								}
							);
						} // </else
						return textarea.data(
							'editor',
							{
								type: editorType,
								options: options
							}
						); // </return
					} // </CreateEditor
					return textarea;
				},
				
				/*
				** @name:
				**   destroyEditor
				** @path:
				**   jSam -> destroyEditor
				** @description:
				**   Удалить визуальный редактор
				** @type:
				**   Function
				** @api:
				**   jSam.destroyEditor( type, textarea );
				** @param "textarea":
				**   jQuery Object - DOM-узел
				** @returns:
				**   jQuery Object
				** @example:
				**   jSam.destroyEditor( $( '#ta' ) );
				*/
				destroyEditor: function( textarea ){
					var type = _.detectEditor( textarea );
					if( type && _.data.isRules && _.editors[ type ].destroy ){
						_.editors[ type ].destroy( textarea.get( 0 ) );
					}
					return textarea.removeData( '_editor' ).removeData( 'editor' );
				},
				
				/*
				** @name:
				**   detectEditor
				** @path:
				**   jSam -> detectEditor
				** @description:
				**   Определить, каким визуальным редактором является textarea
				** @type:
				**   Function
				** @api:
				**   jSam.detectEditor( textarea );
				** @param "textarea":
				**   jQuery Object - DOM-узел
				** @returns:
				**   String - тип редактора или пустая строка
				** @example:
				**   jSam.detectEditor( $( '#ta' ) );
				*/
				detectEditor: function( textarea ){
					TextareaManager: {
						if( _.isDOM( textarea ) ){
							textarea = $( textarea );
						}
						if( !_.is$( textarea ) || !textarea.length || !textarea.attr( 'id' ) ){
							return '';
						}
					} // </TextareaManager
					var
						_textarea = textarea.get( 0 ),
						type = '',
						result = '',
						data;
					if( !_.data.isRules && ( data = textarea.data( '_editor' ) ) ){
						type = ( _.isString( data ) ? data : data.type ).toLowerCase();
						return ( result = _.editors[ type ] ) && ( result.hasOwnProperty( 'object' ) ? window[ result.object ] : true ) ? type : '';
					}
					foreach(
						_.editors,
						function( editor, key ){
							if( !result && editor.is && editor.is( _textarea ) ){
								result = key.toLowerCase();
							}
						}
					);
					return result;
				},
				
				/*
				** @name:
				**   editorValue
				** @path:
				**   jSam -> editorValue
				** @description:
				**   Получить/Назначить значение визуального редактора
				** @type:
				**   Function
				** @api:
				**   jSam.editorValue( textarea, value );
				** @param "textarea":
				**   jQuery Object - DOM-узел
				** @param "value":
				**   String
				** @returns:
				**   String
				** @example:
				**   jSam.editorValue( $( '#ta' ) );
				**   jSam.editorValue( $( '#ta' ), "Value 1<br>Value 2" );
				*/
				editorValue: function( textarea, value ){
					var type;
					value = _.isNumberOrString( value ) ? value.toString() : '';
					if( !_.data.isRules ){
						if( arguments.length > 1 ){
							textarea.val( value );
						}
						return textarea.val();
					}
					else if( ( type = _.detectEditor( textarea ) ) ){
						if( arguments.length > 1 ){
							arguments[ 1 ] = value;
						}
						arguments[ 0 ] = textarea.get( 0 );
						return _.editors[ type ].val.apply( this, arguments );
					}
					return '';
				},
				
				
				//*******************//
				//***** Объекты *****//
				//*******************//
				
				
				/*
				** @name:
				**   webElements
				** @path:
				**   jSam -> webElements
				** @description:
				**   Объект web-элементов
				** @type:
				**   Object
				*/
				'webElements': {
					
					/*
					** @name:
					**   text
					** @path:
					**   jSam -> webElements -> text
					** @description:
					**   Объект для управления web-элементом типа "text"
					**   Стандартный текстовый элемент, представляющий из себя контейнер, содержащий DOM-узел <input type="text">
					** @type:
					**   Object
					*/
					'text': {
						
						/*
						** @name:
						**   create
						** @path:
						**   jSam -> webElements -> text -> create
						** @description:
						**   Создать web-элемент типа "text"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.text.create( box, options );
						** @param "options":
						**   Object - Опции web-элемента*
						**   * - смотреть функцию jSam.createWebElement
						** @returns:
						**   jQuery Object - контейнер - web-элемент
						** @rexample:
						**   jSam.webElements.text.create( $( '[name="longtitle"]' ).parent().empty() );
						**   jSam.webElements.text.create( $( '[name="longtitle"]' ).parent().empty(), { attr:{ style:'color:red;' } } );
						*/
						create: function( box, options ){
							return box
								.append(
									$( '<input/>' )
									.attr( ( options = options || {} ).attr || {} )
									.attr( 'type', 'text' )
								)
								.data(
									'webElement',
									{
										'type'      :  'text',
										'options'   :  options
									}
								);
						}, // </create
						
						/*
						** @name:
						**   val
						** @path:
						**   jSam -> webElements -> text -> val
						** @description:
						**   Получить/Установить значение web-элемента
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.text.setValue( webElement, value );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @param "value":
						**   String - новое значение для web-элемента(Необязательно)
						** @returns:
						**   String - значение элемента
						** @rexample:
						**   jSam.webElements.text.val( $( '[name="pagetitle"]' ).parent() );
						**   jSam.webElements.text.val( $( '[name="pagetitle"]' ).parent(), 'New value!' );
						*/
						val: function( webElement, value ){
							var input = webElement.children( 'input' ).eq( 0 );
							if( arguments.length > 1 ){
								input.val( _.isNumberOrString( value ) ? value : '' );
							}
							return input.val() || '';
						}, // </val
						
						/*
						** @name:
						**   is
						** @path:
						**   jSam -> webElements -> text -> is
						** @description:
						**   Проверить, является ли web-элемент элементом типа "text"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.text.is( webElement );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @returns:
						**   Boolean
						** @rexample:
						**   jSam.webElements.text.is( $( '#ta' ).parent() );                        // false
						**   jSam.webElements.text.is( $( '[name="pagetitle"]' ).parent() );         // true
						*/
						is: function( webElement ){
							var elem = webElement.children( '[name]' )
								.filter( function(){ return this.style.display != 'none' && this.type != 'hidden'; } );
							return elem.length == 1 && elem.attr( 'type' ) == 'text' && !elem.data( 'colorpicker' );
						} // </is
						
					}, // </text
					
					/*
					** @name:
					**   textarea
					** @path:
					**   jSam -> webElements -> textarea
					** @description:
					**   Объект для управления web-элементом типа "textarea"
					**   Стандартная текстовая область, представляющая из себя контейнер, содержащий DOM-узел <textarea></textarea>
					** @type:
					**   Object
					** @returns:
					*/
					'textarea': {
						
						/*
						** @name:
						**   create
						** @path:
						**   jSam -> webElements -> textarea -> create
						** @description:
						**   Создать web-элемент типа "textarea"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.textarea.create( box, options );
						** @param "options":
						**   Object - Опции web-элемента*
						**   * - смотреть функцию jSam.createWebElement
						** @returns:
						**   jQuery Object - контейнер - web-элемент
						** @rexample:
						**   jSam.webElements.textarea.create( $( '[name="longtitle"]' ).parent().empty() );
						**   jSam.webElements.textarea.create( $( '[name="longtitle"]' ).parent().empty(), { attr:{ style:'color:red;' } } );
						*/
						create: function( box, options ){
							return box
								.append(
									$( '<textarea/>' )
									.attr( ( options = options || {} ).attr || {} )
									.attr(
										{
											'rows': 15,
											'cols': 60
										}
									)
									.css(
										{
											'width'   :  '100%',
											'height'  :  '150px'
										}
									)
								)
								.data(
									'webElement',
									{
										'type'      :  'textarea',
										'options'   :  options
									}
								);
						}, // </create
						
						/*
						** @name:
						**   val
						** @path:
						**   jSam -> webElements -> textarea -> val
						** @description:
						**   Получить/Установить значение web-элемента
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.textarea.val( webElement, value );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @param "value":
						**   String - новое значение для web-элемента(Необязательно)
						** @returns:
						**   String - значение элемента
						** @rexample:
						**   jSam.webElements.textarea.val( $( '[name="introtext"]' ).parent() );
						**   jSam.webElements.textarea.val( $( '[name="introtext"]' ).parent(), "\tMulti...\n\t...line" );
						*/
						val: function( webElement, value ){
							var elem = webElement.children( 'textarea' ).eq( 0 );
							if( arguments.length > 1 ){
								elem.val( _.isNumberOrString( value ) ? value : '' );
							}
							return elem.val() || '';
						}, // </val
						
						/*
						** @name:
						**   is
						** @path:
						**   jSam -> webElements -> textarea -> is
						** @description:
						**   Проверить, является ли web-элемент элементом типа "text"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.textarea.is( webElement );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @returns:
						**   Boolean
						** @rexample:
						**   jSam.webElements.textarea.is( $( '[name="introtext"]' ).parent() );
						*/
						is: function( webElement ){
							var elem = webElement.children( '[name]' )
								.filter( function(){ return this.style.display != 'none' && this.type != 'hidden'; } );
							return elem.length == 1 && elem.is( 'textarea' ) && !elem.data( 'editor' ) && !elem.data( '_editor' );
						} // </is
						
					}, // </textarea
					
					/*
					** @name:
					**   miniarea
					** @path:
					**   jSam -> webElements -> miniarea
					** @description:
					**   Объект для управления web-элементом типа "miniarea"
					**   Стандартная уменьшенная текстовая область, представляющая из себя контейнер, содержащий DOM-узел textarea, ширина которого 300 пикселей
					** @type:
					**   Object
					** @returns:
					*/
					'miniarea': {
						
						/*
						** @name:
						**   create
						** @path:
						**   jSam -> webElements -> miniarea -> create
						** @description:
						**   Создать web-элемент типа "miniarea"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.miniarea.create( box, options );
						** @param "options":
						**   Object - Опции web-элемента*
						**   * - смотреть функцию jSam.createWebElement
						** @returns:
						**   jQuery Object - контейнер - web-элемент
						** @rexample:
						**   jSam.webElements.miniarea.create( $( '[name="longtitle"]' ).parent().empty() );
						**   jSam.webElements.miniarea.create( $( '[name="longtitle"]' ).parent().empty(), { attr:{ style:'color:red;' } } );
						*/
						create: function( box, options ){
							return box
								.append(
									$( '<textarea/>' )
									.attr( ( options = options || {} ).attr || {} )
									.attr( 'class', 'inputBox' )
									.css(
										{
											'width'   :  '300px',
											'height'  :  '75px'
										}
									)
								)
								.data(
									'webElement',
									{
										'type'      :  'miniarea',
										'options'   :  options
									}
								);
						}, // </create
						
						/*
						** @name:
						**   val
						** @path:
						**   jSam -> webElements -> miniarea -> val
						** @description:
						**   Получить/Установить значение web-элемента
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.miniarea.val( webElement, value );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @param "value":
						**   String - новое значение для web-элемента(Необязательно)
						** @returns:
						**   String - значение элемента
						** @rexample:
						**   jSam.webElements.miniarea.val( $( '[name="introtext"]' ).parent() );
						**   jSam.webElements.miniarea.val( $( '[name="introtext"]' ).parent(), "\tMulti...\n\t...line" );
						*/
						val: function( webElement, value ){
							var elem = webElement.children( 'textarea' ).eq( 0 );
							if( arguments.length > 1 ){
								elem.val( _.isNumberOrString( value ) ? value : '' );
							}
							return elem.val() || '';
						}, // </val
						
						/*
						** @name:
						**   is
						** @path:
						**   jSam -> webElements -> miniarea -> is
						** @description:
						**   Проверить, является ли web-элемент элементом типа "text"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.miniarea.is( webElement );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @returns:
						**   Boolean
						** @rexample:
						**   jSam.webElements.miniarea.is( $( '[name="introtext"]' ).parent() );
						*/
						is: function( webElement ){
							var elem = webElement.children( '[name]' )
								.filter( function(){ return this.style.display != 'none' && this.type != 'hidden'; } );
							return elem.length == 1 && elem.is( 'textarea' ) && !elem.data( 'editor' ) && !elem.data( '_editor' ) && elem.width() == 300;
						} // </is
						
					}, // </miniarea
					
					/*
					** @name:
					**   menubox
					** @path:
					**   jSam -> webElements -> menubox
					** @description:
					**   Объект для управления web-элементом типа "menubox"
					**   Cтандартный выпадающий список, представляющий из себя контейнер, содержащий DOM-узел select
					** @type:
					**   Object
					*/
					'menubox': {
						
						/*
						** @name:
						**   create
						** @path:
						**   jSam -> webElements -> menubox -> create
						** @description:
						**   Создать web-элемент типа "menubox"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.menubox.create( box, options );
						** @param "options":
						**   Object - Опции web-элемента(*)(**)
						**   (*) - смотреть функцию jSam.createWebElement
						**   (**) - Дополнительные опции
						**     {
						**       multiple   : Boolean,   // Разрешить выбор нескольких значений(Превращение в web-элемент типа "multibox")
						**       size       : Number     // Количество видимых вариантов для выбора(По умолчанию: 1)Превращение в web-элемент типа "listbox")
						**     }
						** @returns:
						**   jQuery Object - контейнер - web-элемент
						** @rexample:
						**   jSam.webElements.menubox.create( $( '[name="longtitle"]' ).parent().empty() );
						**   jSam.webElements.menubox.create( $( '[name="longtitle"]' ).parent().empty(), { values: 'Value', attr:{ style:'color:red;width:200px;' } } );
						**   jSam.webElements.menubox.create( $( '[name="longtitle"]' ).parent().empty(), { values: [ 1, 2, 3 ], attr: { name: 'longtitle' } } );
						**   jSam.webElements.menubox.create( $( '[name="longtitle"]' ).parent().empty(), { multiple: true, values: [ 1, 2, 3 ], attr: { name: 'longtitle' } } );
						**   jSam.webElements.menubox.create( $( '[name="longtitle"]' ).parent().empty(), { multiple: true, size: 2, values: [ 1, 2, 3 ] } );
						**   jSam.webElements.menubox.create( $( '[name="longtitle"]' ).parent().empty(), { size: 4, values: { '1 - 1': 1, '2 - 2': 2, '3 - 3': 3, '4 - 4': 4, '5 - 5': 5, '6 - 6': 6, '7 - 7': 7 } } );
						*/
						create: function( box, options ){
							var select = $( '<select/>' )
								.attr( ( options = options || {} ).attr || {} )
								.appendTo( box )
								.get( 0 );
							SetSize: {
								if( _.isNumberOrString( options.size ) ){
									select.size = parseInt( options.size );
								}
							} // </SetSize
							SetMultiple: {
								if( options.multiple ){
									select.multiple = true;
								}
							} // </SetMultiple
							SetValues: {
								if( options.hasOwnProperty( 'values' ) ){
									jSam.webElements.menubox.values( box, options.values );
								}
							} // </SetValues
							return box
								.data(
									'webElement',
									{
										'type'     :  select.multiple ? 'multibox' : select.size > 1 ? 'listbox' : 'menubox',
										'options'  :  options
									}
								);
						}, // </create
						
						/*
						** @name:
						**   values
						** @path:
						**   jSam -> webElements -> menubox -> values
						** @description:
						**   Установить web-элементу возможные значения
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.menubox.values( webElement, values );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @param "values":
						**   String - значение для web-элемента
						**   Array - массив значений web-элемента
						**   Object - ассециативный массив значений web-элемента
						** @returns:
						**   jQuery Object - контейнер - web-элемент
						** @rexample:
						**   jSam.webElements.menubox.values( $( '[name="type"]' ).parent().eq( 0 ), 'New Value!' );
						**   jSam.webElements.menubox.values( $( '[name="type"]' ).parent().eq( 0 ), [ 'Value 1', 'Value 2', 'Value 3' ] );
						**   jSam.webElements.menubox.values( $( '[name="type"]' ).parent().eq( 0 ), { 'Value 1': 101, 'Value 2': 102, 'Value 3': 103 } );
						*/
						values: function( webElement, values ){
							values = _.isNumber( values ) ? [ values + '' ] : _.isString( values ) ? [ values ] : values;
							var
								elem = webElement.children( 'select' ).eq( 0 ),
								fragment = $(),
								isArray = $.isArray( values );
							if( _.isPrimitive( values ) ){
								elem.html( '' );
							}
							else{
								foreach(
									values,
									function( val, key ){
										fragment = fragment.add( $( '<option/>' ).val( val ).html( isArray ? val : key ) );
									}
								);
								elem = elem.html( fragment ).get( 0 );
								var name = elem.name;
								if( elem.multiple && fragment.length > 1 && name != '' && !/\[\]$/.test( name ) ){
									elem.name = name + '[]';
								}
							}
							elem.selectedIndex = -1;
							return webElement;
						}, // </values
						
						/*
						** @name:
						**   val
						** @path:
						**   jSam -> webElements -> menubox -> val
						** @description:
						**   Получить/Установить значение web-элемента
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.menubox.val( webElement, value );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @param "value":
						**   String - новое значение для web-элемента(Необязательно)
						** @returns:
						**   String
						**   Array
						** @rexample:
						**   jSam.webElements.menubox.val( $( '[name="type"]' ).parent() );
						**   jSam.webElements.menubox.val( $( '[name="type"]' ).parent(), 'reference' );
						**   jSam.webElements.menubox.val( $( '[name="tv5[]"]' ).parent() );
						*/
						val: function( webElement, value ){
							var
								_elem = webElement.children( 'select' ).eq( 0 ),
								elem = _elem.get( 0 );
							if( arguments.length > 1 ){
								if( _.isNumberOrString( value ) ){
									value = [ value ];
								}
								if( _.isPrimitive( value ) ){
									value = [];
								}
								var isSelected = !!_elem
									.find( 'option' )
									.each(
										function(){
											this.selected = $.inArray( this.value, value ) != -1;
										}
									)
									.filter( '[selected]' )
									.size();
								if( !isSelected ){
									elem.selectedIndex = -1;
								}
							}
							if( !elem.multiple ){
								return elem.options.length == 0 || elem.selectedIndex == -1 ? null : elem.options[ elem.selectedIndex ].value;
							}
							else{
								value = _elem.children( 'option[selected]' ).toArray();
								return value.length ? value : null;
							}
						}, // </val
						
						/*
						** @name:
						**   is
						** @path:
						**   jSam -> webElements -> menubox -> is
						** @description:
						**   Проверить, является ли web-элемент элементом типа "text"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.menubox.is( webElement );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @returns:
						**   Boolean
						** @rexample:
						**   jSam.webElements.menubox.is( $( '[name="type"]' ).parent() );
						*/
						is: function( webElement ){
							var elem = webElement.children( '[name]' )
								.filter( function(){ return this.style.display != 'none' && this.type != 'hidden'; } );
							return elem.length == 1 && elem.is( 'select' );
						} // </is
						
					}, // </menubox
					
					/*
					** @name:
					**   listbox
					** @path:
					**   jSam -> webElements -> listbox
					** @description:
					**   Объект для управления web-элементом типа "listbox"
					**   Стандартный пунктный список для выбора одного значения, представляющий из себя контейнер, содержащий DOM-узел select
					** @type:
					**   Object
					*/
					'listbox': {
						
						/*
						** @name:
						**   create
						** @path:
						**   jSam -> webElements -> listbox -> create
						** @description:
						**   Создать web-элемент типа "listbox"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.listbox.create( box, options );
						** @param "options":
						**   Object - Опции web-элемента(*)(**)
						**   (*) - смотреть функцию jSam.createWebElement
						**   (**) - Дополнительные опции
						**     {
						**       size: Number     // Количество видимых вариантов для выбора(По умолчанию: 1)Превращение в web-элемент типа "listbox")
						**     }
						** @returns:
						**   jQuery Object - контейнер - web-элемент
						** @rexample:
						**   jSam.webElements.listbox.create( $( '[name="longtitle"]' ).parent().empty() );
						**   jSam.webElements.listbox.create( $( '[name="longtitle"]' ).parent().empty(), { values: [ 'AA', 'BB' ], attr:{ style:'color:red;width:200px;' } } );
						**   jSam.webElements.listbox.create( $( '[name="longtitle"]' ).parent().empty(), { values: [ 1, 2, 3 ], attr: { name: 'longtitle' } } );
						**   jSam.webElements.listbox.create( $( '[name="longtitle"]' ).parent().empty(), { values: ['AA','BB','CC','DD','EE','FF'], size: 4 } );
						*/
						create: function( box, options ){
							( options = options || {} ).size = ( options.attr && options.attr.size || options.size || 8 );
							return jSam.webElements.menubox.create( box, options );
						}, // </create
						
						/*
						** @name:
						**   values
						** @path:
						**   jSam -> webElements -> listbox -> values
						** @description:
						**   Установить web-элементу возможные значения
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.listbox.values( webElement, values );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @param "values":
						**   String - значение для web-элемента
						**   Array - массив значений web-элемента
						**   Object - ассециативный массив значений web-элемента
						** @returns:
						**   jQuery Object - контейнер - web-элемент
						** @rexample:
						**   jSam.webElements.listbox.values( $( '[name="tv4"]' ).parent().eq( 0 ), [ 'Value 1', 'Value 2', 'Value 3' ] );
						**   jSam.webElements.listbox.values( $( '[name="tv4"]' ).parent().eq( 0 ), { 'Value 1': 101, 'Value 2': 102, 'Value 3': 103 } );
						*/
						values: function( webElement, values ){
							return jSam.webElements.menubox.values.apply( this, arguments );
						}, // </values
						
						/*
						** @name:
						**   val
						** @path:
						**   jSam -> webElements -> listbox -> val
						** @description:
						**   Получить/Установить значение web-элемента
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.listbox.val( webElement, value );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @param "value":
						**   String - новое значение для web-элемента(Необязательно)
						** @returns:
						**   String
						**   Array
						** @rexample:
						**   jSam.webElements.listbox.val( $( '[name="tv4"]' ).parent(), '65' );
						*/
						val: function( webElement, value ){
							return jSam.webElements.menubox.val.apply( this, arguments );
						}, // </val
						
						/*
						** @name:
						**   is
						** @path:
						**   jSam -> webElements -> listbox -> is
						** @description:
						**   Проверить, является ли web-элемент элементом типа "text"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.listbox.is( webElement );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @returns:
						**   Boolean
						** @rexample:
						**   jSam.webElements.listbox.is( $( '[name="tv4"]' ).parent() );
						*/
						is: function( webElement ){
							var elem = webElement.children( '[name]' )
								.filter( function(){ return this.style.display != 'none' && this.type != 'hidden'; } );
							return elem.length == 1 && elem.is( 'select' ) && elem[ 0 ].size > 1 && !elem[ 0 ].multiple;
						} // </is
						
					}, // </listbox
					
					/*
					** @name:
					**   multibox
					** @path:
					**   jSam -> webElements -> multibox
					** @description:
					**   Объект для управления web-элементом типа "multibox"
					**   Стандартный пунктный список для выбора нескольких значений, представляющий из себя контейнер, содержащий DOM-узел select
					** @type:
					**   Object
					*/
					'multibox': {
						
						/*
						** @name:
						**   create
						** @path:
						**   jSam -> webElements -> multibox -> create
						** @description:
						**   Создать web-элемент типа "multibox"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.multibox.create( box, options );
						** @param "options":
						**   Object - Опции web-элемента(*)(**)
						**   (*) - смотреть функцию jSam.createWebElement
						**   (**) - Дополнительные опции
						**     {
						**       size: Number     // Количество видимых вариантов для выбора(По умолчанию: 1)Превращение в web-элемент типа "multibox")
						**     }
						** @returns:
						**   jQuery Object - контейнер - web-элемент
						** @rexample:
						**   jSam.webElements.multibox.create( $( '[name="longtitle"]' ).parent().empty() );
						**   jSam.webElements.multibox.create( $( '[name="longtitle"]' ).parent().empty(), { values: [ 'AA', 'BB' ], attr:{ style:'color:red;width:200px;' } } );
						**   jSam.webElements.multibox.create( $( '[name="longtitle"]' ).parent().empty(), { values: [ 1, 2, 3 ], attr: { name: 'longtitle' } } );
						**   jSam.webElements.multibox.create( $( '[name="longtitle"]' ).parent().empty(), { values: ['AA','BB','CC','DD','EE','FF'], size: 4 } );
						*/
						create: function( box, options ){
							( options = options || {} ).multiple = true;
							return jSam.webElements.menubox.create( box, options );
						}, // </create
						
						/*
						** @name:
						**   values
						** @path:
						**   jSam -> webElements -> multibox -> values
						** @description:
						**   Установить web-элементу возможные значения
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.multibox.values( webElement, values );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @param "values":
						**   String - значение для web-элемента
						**   Array - массив значений web-элемента
						**   Object - ассециативный массив значений web-элемента
						** @returns:
						**   jQuery Object - контейнер - web-элемент
						** @rexample:
						**   jSam.webElements.multibox.values( $( '[name="tv5[]"]' ).parent().eq( 0 ), [ 'Value 1', 'Value 2', 'Value 3' ] );
						**   jSam.webElements.multibox.values( $( '[name="tv5[]"]' ).parent().eq( 0 ), { 'Value 1': 101, 'Value 2': 102, 'Value 3': 103 } );
						*/
						values: function( webElement, values ){
							return jSam.webElements.menubox.values.apply( this, arguments );
						}, // </values
						
						/*
						** @name:
						**   val
						** @path:
						**   jSam -> webElements -> multibox -> val
						** @description:
						**   Получить/Установить значение web-элемента
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.multibox.val( webElement, value );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @param "value":
						**   String - новое значение для web-элемента(Необязательно)
						** @returns:
						**   String
						**   Array
						** @rexample:
						**   jSam.webElements.multibox.val( $( '[name="tv5[]"]' ).parent(), null );
						**   jSam.webElements.multibox.val( $( '[name="tv5[]"]' ).parent(), '7888' );
						**   jSam.webElements.multibox.val( $( '[name="tv5[]"]' ).parent(), [ 'ABC', '7888' ] );
						*/
						val: function( webElement, value ){
							return jSam.webElements.menubox.val.apply( this, arguments );
						}, // </val
						
						/*
						** @name:
						**   is
						** @path:
						**   jSam -> webElements -> multibox -> is
						** @description:
						**   Проверить, является ли web-элемент элементом типа "text"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.multibox.is( webElement );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @returns:
						**   Boolean
						** @rexample:
						**   jSam.webElements.multibox.is( $( '[name="tv5[]"]' ).parent() );
						*/
						is: function( webElement ){
							var elem = webElement.children( '[name]' )
								.filter( function(){ return this.style.display != 'none' && this.type != 'hidden'; } );
							return elem.length == 1 && elem.is( 'select' ) && elem[ 0 ].multiple;
						} // </is
						
					}, // </multibox
					
					/*
					** @name:
					**   checkbox
					** @path:
					**   jSam -> webElements -> checkbox
					** @description:
					**   Объект для управления web-элементом типа "checkbox"
					**   Cтандартный список элементов для их выбора, представляющий из себя контейнер, содержащий DOM-узлы <input type="checkbox">
					** @type:
					**   Object
					*/
					'checkbox': {
						
						/*
						** @name:
						**   create
						** @path:
						**   jSam -> webElements -> checkbox -> create
						** @description:
						**   Создать web-элемент типа "checkbox"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.checkbox.create( box, options );
						** @param "options":
						**   Object - Опции web-элемента(*)
						**   (*) - смотреть функцию jSam.createWebElement
						** @returns:
						**   jQuery Object - контейнер - web-элемент
						** @rexample:
						**   jSam.webElements.checkbox.create( $( '[name="longtitle"]' ).parent().empty(), { values: '' } );
						**   jSam.webElements.checkbox.create( $( '[name="longtitle"]' ).parent().empty(), { values: [ 123, 456, 789 ], attr: { name: 'longtitle' } } );
						**   jSam.webElements.checkbox.create( $( '[name="longtitle"]' ).parent().empty(), { values: { 'Value 1': 123, 'Value 2': 456 } } );
						*/
						create: function( box, options ){
							SetValues: {
								if( options.hasOwnProperty( 'values' ) ){
									jSam.webElements.checkbox.values( box, options.values, options.attr );
								}
							} // </SetValues
							return box
								.data(
									'webElement',
									{
										'type'     :  'checkbox',
										'options'  :  options
									}
								);
						}, // </create
						
						/*
						** @name:
						**   values
						** @path:
						**   jSam -> webElements -> checkbox -> values
						** @description:
						**   Установить web-элементу возможные значения
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.checkbox.values( webElement, values );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @param "values":
						**   String - значение для web-элемента
						**   Array - массив значений web-элемента
						**   Object - ассециативный массив значений web-элемента
						** @returns:
						**   jQuery Object - контейнер - web-элемент
						** @rexample:
						**   jSam.webElements.checkbox.values( $( '[name="hidemenucheck"]' ).parent().eq( 0 ).empty(), 'New Value!' );
						**   jSam.webElements.checkbox.values( $( '[name="hidemenucheck"]' ).parent().eq( 0 ).empty(), 'Value!', { name: 'field1' } );
						**   jSam.webElements.checkbox.values( $( '[name="hidemenucheck"]' ).parent().eq( 0 ).empty(), [ 'Value 1', 'Value 2', 'Value 3' ], { name: 'field2' } );
						**   jSam.webElements.checkbox.values( $( '[name="hidemenucheck"]' ).parent().eq( 0 ).empty(), { 1: 101, 2: 102, 3: 103 } , { name: 'field3' } );
						**   jSam.webElements.checkbox.values( $( '[name="hidemenucheck"]' ).parent().eq( 0 ).empty(), '' );
						*/
						values: function( webElement, values, attr ){
							if( _.isPrimitive( attr ) ){
								attr = {};
							}
							if( !attr.name ){
								attr.name = 'element-' + _.getUnique();
							}
							if( _.isNumberOrString( values ) ){
								values = [ values ];
							}
							var
								fragment = $(),
								id,
								i = 0,
								isArray = $.isArray( values ),
								input,
								label;
							if( isArray || !_.isPrimitive( values ) ){
								foreach(
									values,
									function( v, key ){
										fragment = fragment
										.add(
											input = $( '<input/>' )
											.css(
												{
													'height'          : 'auto !important',
													'width'           : 'auto !important',
													'vertical-align'  : 'middle'
												}
											)
											.attr(
												extend(
													{
														type: 'checkbox',
														id: id = 'tv_' + _.getUnique()
													},
													attr
												)
											)
											.addClass( 'checkbox' )
										);
										if( v.toString() != '' ){
											input.val( v );
											fragment = fragment
											.add(
												$( '<label/>' )
												.attr( 'for', id )
												.html( isArray ? v : key )
											)
										}
										fragment = fragment.add( '<br>' );
										i++;
									}
								);
							}
							var len = fragment.length;
							fragment = fragment.filter(
								function( i ){
									return i != len - 1;
								}
							);
							var elements = fragment.filter( ':checkbox' );
							if( elements.length > 1 ){
								var name = elements.eq( 0 ).attr( 'name' );
								elements.attr( 'name', /\[\]$/.test( name ) ? name : name + '[]' );
							}
							return webElement.prepend( fragment );
						}, // </values
						
						/*
						** @name:
						**   val
						** @path:
						**   jSam -> webElements -> checkbox -> val
						** @description:
						**   Получить/Установить значение web-элемента
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.checkbox.val( webElement, value );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @param "value":
						**   String - новое значение для web-элемента(Необязательно)
						** @returns:
						**   String
						**   Array
						** @rexample:
						**   jSam.webElements.checkbox.val( $( '[name="hidemenucheck"]' ).parent(), true );
						**   jSam.webElements.checkbox.val( $( '[name="tv5[]"]' ).parent(), [ 'AA', 'BB' ] );
						*/
						val: function( webElement, value ){
							var
								elements = webElement.children( ':checkbox' ),
								array = [],
								isArray = /\[\]$/.test( elements.eq( 0 ).attr( 'name' ) );
							value = _.isNumberOrString( value ) ? [ value + '' ] : value;
							if( arguments.length > 1 ){
								if( _.getName( value ) == 'Boolean' ){
									elements.get( 0 ).checked = value;
								}
								else{
									elements
									.each(
										function(){
											this.checked = $.inArray( this.value, value );
										}
									)
								}
							}
							elements = elements.filter( '[checked]' );
							if( !isArray ){
								if( elements.length ){
									var elem = elements.get( -1 );
									return _.isAttribute( elem, 'value' ) ? elem.value : elem.checked ? 1 : 0;
								}
								else{
									return null;
								}
							}
							else{
								value = elements
									.map(
										function(){
											return this.value;
										}
									)
									.toArray();
								return value.length ? value : null;
							}
						}, // </val
						
						/*
						** @name:
						**   is
						** @path:
						**   jSam -> webElements -> checkbox -> is
						** @description:
						**   Проверить, является ли web-элемент элементом типа "text"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.checkbox.is( webElement );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @returns:
						**   Boolean
						** @rexample:
						**   jSam.webElements.checkbox.is( $( '[name="hidemenucheck"]' ).parent() );
						*/
						is: function( webElement ){
							var elem = webElement.children( '[name]' )
								.filter( function(){ return this.style.display != 'none' && this.type != 'hidden'; } );
							return elem.length && elem.is( ':checkbox' );
						} // </is
						
					}, // </checkbox
					
					/*
					** @name:
					**   radiobox
					** @path:
					**   jSam -> webElements -> radiobox
					** @description:
					**   Объект для управления web-элементом типа "radiobox"
					**   Cтандартный список элементов выбора одного элемента, представляющий из себя контейнер, содержащий DOM-узлы <input type="radio">
					** @type:
					**   Object
					*/
					'radiobox': {
						
						/*
						** @name:
						**   create
						** @path:
						**   jSam -> webElements -> radiobox -> create
						** @description:
						**   Создать web-элемент типа "radiobox"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.radiobox.create( box, options );
						** @param "options":
						**   Object - Опции web-элемента(*)
						**   (*) - смотреть функцию jSam.createWebElement
						** @returns:
						**   jQuery Object - контейнер - web-элемент
						** @rexample:
						**   jSam.webElements.radiobox.create( $( '[name="longtitle"]' ).parent().empty(), { values: [ 123, 456, 789 ], attr: { name: 'longtitle' } } );
						**   jSam.webElements.radiobox.create( $( '[name="longtitle"]' ).parent().empty(), { values: { 'Value 1': 123, 'Value 2': 456 } } );
						*/
						create: function( box, options ){
							SetValues: {
								if( options.hasOwnProperty( 'values' ) ){
									jSam.webElements.radiobox.values( box, options.values, options.attr );
								}
							} // </SetValues
							return box
								.data(
									'webElement',
									{
										'type'     :  'radiobox',
										'options'  :  options
									}
								);
						}, // </create
						
						/*
						** @name:
						**   values
						** @path:
						**   jSam -> webElements -> radiobox -> values
						** @description:
						**   Установить web-элементу возможные значения
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.radiobox.values( webElement, values );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @param "values":
						**   String - значение для web-элемента
						**   Array - массив значений web-элемента
						**   Object - ассециативный массив значений web-элемента
						** @returns:
						**   jQuery Object - контейнер - web-элемент
						** @rexample:
						**   jSam.webElements.radiobox.values( $( '[name="hidemenucheck"]' ).parent().eq( 0 ).empty(), 'New Value!' );
						**   jSam.webElements.radiobox.values( $( '[name="hidemenucheck"]' ).parent().eq( 0 ).empty(), 'Value!', { name: 'field1' } );
						**   jSam.webElements.radiobox.values( $( '[name="hidemenucheck"]' ).parent().eq( 0 ).empty(), [ 'Value 1', 'Value 2', 'Value 3' ], { name: 'field2' } );
						**   jSam.webElements.radiobox.values( $( '[name="hidemenucheck"]' ).parent().eq( 0 ).empty(), { 1: 101, 2: 102, 3: 103 } , { name: 'field3' } );
						*/
						values: function( webElement, values, attr ){
							if( _.isPrimitive( attr ) ){
								attr = {};
							}
							if( !attr.name ){
								attr.name = 'element-' + _.getUnique();
							}
							if( _.isNumberOrString( values ) ){
								values = [ values ];
							}
							var
								fragment = $(),
								id,
								i = 0,
								isArray = $.isArray( values ),
								input,
								label;
							if( isArray || !_.isPrimitive( values ) ){
								foreach(
									values,
									function( v, key ){
										fragment = fragment
										.add(
											input = $( '<input/>' )
											.css(
												{
													'height'          : 'auto !important',
													'width'           : 'auto !important',
													'vertical-align'  : 'middle'
												}
											)
											.attr(
												extend(
													{
														type: 'radio',
														id: id = 'tv_' + _.getUnique()
													},
													attr
												)
											)
											.addClass( 'radiobox' )
										);
										if( v.toString() != '' ){
											input.val( v );
											fragment = fragment
											.add(
												$( '<label/>' )
												.attr( 'for', id )
												.html( isArray ? v : key )
											)
										}
										fragment = fragment.add( '<br>' );
										i++;
									}
								);
							}
							var len = fragment.length;
							fragment = fragment.filter(
								function( i ){
									return i != len - 1;
								}
							);
							return webElement.prepend( fragment );
						}, // </values
						
						/*
						** @name:
						**   val
						** @path:
						**   jSam -> webElements -> radiobox -> val
						** @description:
						**   Получить/Установить значение web-элемента
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.radiobox.val( webElement, value );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @param "value":
						**   String - новое значение для web-элемента(Необязательно)
						** @returns:
						**   String
						**   Array
						** @rexample:
						**   jSam.webElements.radiobox.val( $( '[name="longtitle"]' ).parent() );
						**   jSam.webElements.radiobox.val( $( '[name="longtitle"]' ).parent(), '789' );
						*/
						val: function( webElement, value ){
							var
								elems = webElement.children( ':radio' ),
								elem;
							if( arguments.length > 1 ){
								elems
								.each(
									function(){
										this.checked = this.value == value;
									}
								)
							}
							elem = elems.filter( '[checked]' ).eq( -1 );
							return elem.length ? elem.val() : null;
						}, // </val
						
						/*
						** @name:
						**   is
						** @path:
						**   jSam -> webElements -> radiobox -> is
						** @description:
						**   Проверить, является ли web-элемент элементом типа "text"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.radiobox.is( webElement );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @returns:
						**   Boolean
						** @rexample:
						**   jSam.webElements.radiobox.is( $( '[name="longtitle"]' ).parent() );
						*/
						is: function( webElement ){
							var elem = webElement.children( '[name]' )
								.filter( function(){ return this.style.display != 'none' && this.type != 'hidden'; } );
							return elem.length && elem.is( ':radio' );
						} // </is
						
					}, // </radiobox
					
					/*
					** @name:
					**   number
					** @path:
					**   jSam -> webElements -> number
					** @description:
					**   Объект для управления web-элементом типа "number"
					**   Текстовый элемент для ввода числа, представляющий из себя контейнер, содержащий DOM-узел <input type="text">
					** @type:
					**   Object
					*/
					'number': {
						
						/*
						** @name:
						**   create
						** @path:
						**   jSam -> webElements -> number -> create
						** @description:
						**   Создать web-элемент типа "number"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.number.create( box, options );
						** @param "options":
						**   Object - Опции web-элемента*
						**   * - смотреть функцию jSam.createWebElement
						** @returns:
						**   jQuery Object - контейнер - web-элемент
						** @rexample:
						**   jSam.webElements.number.create( $( '[name="longtitle"]' ).parent().empty() );
						**   jSam.webElements.number.create( $( '[name="longtitle"]' ).parent().empty(), { attr:{ style:'color:red;width:60px;' } } );
						*/
						create: function( box, options ){
							var id = 'element-' + _.getUnique();
							id = (
								( options = options || {} ).attr = extend(
									{
										value: 0,
										id: id,
										type: 'text'
									},
									options.attr || {}
								)
							).id;
							return box
								.append(
									$( '<input/>' )
									.css( 'width', '30px' )
									.attr( options.attr )
									.keyup(
										function(){
											if( !/^-?([0-9]+(\.?[0-9]*)?)?$/.test( this.value ) ){
												this.value = this.value.substr( 0, this.value.length - 1 );
											}
										}
									),
									$( '<input/>' )
									.attr(
										{
											'type'     : 'button',
											'onclick'  : "var elem = document.getElementById( '" + id + "' ), val = parseFloat( elem.value ) - 1; elem.value = !isNaN( val ) ? val : 0; elem.focus(); documentDirty=true;",
											'value'    : '<'
										}
									),
									$( '<input/>' )
									.attr(
										{
											'type'     : 'button',
											'onclick'  : "var elem = document.getElementById( '" + id + "' ), val = parseFloat( elem.value ) + 1; elem.value = !isNaN( val ) ? val : 0; elem.focus(); documentDirty=true;",
											'value'    : '>'
										}
									)
								)
								.data(
									'webElement',
									{
										'type'      :  'number',
										'options'   :  options
									}
								);
						}, // </create
						
						/*
						** @name:
						**   val
						** @path:
						**   jSam -> webElements -> number -> val
						** @description:
						**   Получить/Установить значение web-элемента
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.number.setValue( webElement, value );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @param "value":
						**   String - новое значение для web-элемента(Необязательно)
						** @returns:
						**   String - значение элемента
						** @rexample:
						**   jSam.webElements.number.val( $( '[name="menuindex"]' ).parent() );
						**   jSam.webElements.number.val( $( '[name="menuindex"]' ).parent(), 18 );
						*/
						val: function( webElement, value ){
							var input = webElement.children( 'input' ).eq( 0 );
							if( arguments.length > 1 ){
								input.val( !isNaN( value = parseFloat( value ) ) ? value : 0 );
							}
							value = parseFloat( input.val() );
							return isNaN( value ) ? 0 : value;
						}, // </val
						
						/*
						** @name:
						**   is
						** @path:
						**   jSam -> webElements -> number -> is
						** @description:
						**   Проверить, является ли web-элемент элементом типа "number"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.number.is( webElement );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @returns:
						**   Boolean
						** @rexample:
						**   jSam.webElements.number.is( $( '[name="menuindex"]' ).parent() );
						*/
						is: function( webElement ){
							var
								elements = webElement.children( '[name]' )
									.filter( function(){ return this.style.display != 'none' && this.type != 'hidden'; } );
								input = elements.eq( 0 ),
								buttons = elements.slice( 1, 3 );
							return elements.length == 3 && input.is( ':text' ) && buttons.is( ':button' ) && !input.data( 'colorpicker' );
						} // </is
						
					}, // </number
					
					/*
					** @name:
					**   colorpicker
					** @path:
					**   jSam -> webElements -> colorpicker
					** @description:
					**   Объект для управления web-элементом типа "colorpicker"
					**   Стандартный текстовый элемент, представляющий из себя контейнер, содержащий DOM-узел <input type="text">
					** @type:
					**   Object
					*/
					'colorpicker': {
						
						/*
						** @name:
						**   create
						** @path:
						**   jSam -> webElements -> colorpicker -> create
						** @description:
						**   Создать web-элемент типа "colorpicker"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.colorpicker.create( box, options );
						** @param "options":
						**   Object - Опции web-элемента*
						**   * - смотреть функцию jSam.createWebElement
						** @returns:
						**   jQuery Object - контейнер - web-элемент
						** @rexample:
						**   jSam.webElements.colorpicker.create( $( '[name="longtitle"]' ).parent().empty() );
						**   jSam.webElements.colorpicker.create( $( '[name="longtitle"]' ).parent().empty(), { attr:{ style:'color:red;width:230px;' } } );
						*/
						create: function( box, options ){
							var
								webElement = jSam.webElements.text.create( box, options ),
								picker = $(
										'<div/>',
										{
											'class': 'farbtastic ui-widget ui-widget-content ui-corner-bottom',
											'style': 'display:none;position:absolute;text-align:center;padding:5px;'
										}
									)
									.farbtastic(
										function( color ){
											input
											.val( color )
											.stop( true )
											.animate( { 'background-color': color }, 1000 );
										}
									),
								input = webElement
									.children( ':text' )
									.eq( 0 )
									.focus(
										function(){
											input
											.removeClass( 'ui-corner-top' )
											.addClass( 'ui-corner-top' );
											picker
											.stop( true )
											.fadeIn( 500 );
										}
									)
									.blur(
										function(){
											input
											.removeClass( 'ui-corner-top' );
											picker
											.stop( true )
											.fadeOut( 500 );
										}
									)
									.data( 'colorpicker', true ),
								width = input.outerWidth(),
								value = input.val();
							picker.css( 'margin-top', input.outerHeight() + 'px' );
							input.css( 'background', value.charAt( 0 ) == '#' ? value : '#FFF' );
							if( width > 203 ){
								width = Math.floor( ( width - 207 ) / 2 ) + 5;
								picker
								.css(
									{
										'padding-left': width + 'px',
										'padding-right': width + 'px'
									}
								)
							}
							input.before( picker );
							return box
								.data(
									'webElement',
									{
										'type'      :  'colorpicker',
										'options'   :  options
									}
								);
						}, // </create
						
						/*
						** @name:
						**   val
						** @path:
						**   jSam -> webElements -> colorpicker -> val
						** @description:
						**   Получить/Установить значение web-элемента
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.colorpicker.setValue( webElement, value );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @param "value":
						**   String - новое значение для web-элемента(Необязательно)
						** @returns:
						**   String - значение элемента
						** @rexample:
						**   jSam.webElements.colorpicker.val( $( '[name="longtitle"]' ).parent() );
						**   jSam.webElements.colorpicker.val( $( '[name="longtitle"]' ).parent(), '#ABC' );
						**   jSam.webElements.colorpicker.val( $( '[name="longtitle"]' ).parent(), null );
						*/
						val: function( webElement, value ){
							var input = webElement.children( ':text' ).eq( 0 );
							if( arguments.length > 1 ){
								if( _.isNumber( value ) ){
									value = '#' + value.toString().substr( 0, 6 );
								}
								if( _.isString( value ) ){
									input
									.val( value )
									.css( 'background-color', value.charAt( 0 ) == '#' ? value : '#FFF' );
								}
								else{
									input.val( '' ).css( 'background', '#FFF' );
								}
							}
							value = input.val();
							return value == '' ? null : value;
						}, // </val
						
						/*
						** @name:
						**   is
						** @path:
						**   jSam -> webElements -> colorpicker -> is
						** @description:
						**   Проверить, является ли web-элемент элементом типа "colorpicker"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.colorpicker.is( webElement );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @returns:
						**   Boolean
						** @rexample:
						**   jSam.webElements.colorpicker.is( $( '[name="longtitle"]' ).parent() );
						*/
						is: function( webElement ){
							var elem = webElement.children( '[name]' )
								.filter( function(){ return this.style.display != 'none' && this.type != 'hidden'; } );
							return elem.length == 1 && elem.is( ':text' ) && webElement.children( '.farbtastic' ).length > 0;
						} // </is
						
					}, // </colorpicker
					
					/*
					** @name:
					**   date
					** @path:
					**   jSam -> webElements -> date
					** @description:
					**   Объект для управления web-элементом типа "date"
					**   Тестовый элемент для выбора даты, представляющий из себя контейнер, содержащий DOM-узел <input type="text"> и кнопку вызова виджета
					** @type:
					**   Object
					*/
					'date': {
						
						/*
						** @name:
						**   create
						** @path:
						**   jSam -> webElements -> date -> create
						** @description:
						**   Создать web-элемент типа "date"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.date.create( box, options );
						** @param "options":
						**   Object - Опции web-элемента(*)(**)
						**   * - смотреть функцию jSam.createWebElement
						**   (**) - Дополнительные опции
						**     {
						**       button: Boolean     // Должна ли присутствовать кнопка удаления даты
						**     }
						** @returns:
						**   jQuery Object - контейнер - web-элемент
						** @rexample:
						**   jSam.webElements.date.create( $( '[name="longtitle"]' ).parent().empty() );
						**   jSam.webElements.date.create( $( '[name="longtitle"]' ).parent().empty(), { button: false, attr:{ style:'color:blue;width:278px;' } } );
						*/
						create: function( box, options ){
							options = options || {};
							var
								dpOffset = window.dpOffset || -10,
								dpformat = window.dpformat || _.data.config[ 'datetime_format' ] + ' hh:mm:00',
								webElement = jSam.webElements.text.create( box, options ),
								input = webElement.children( ':text' ).eq( 0 ).addClass( 'DatePicker' ),
								id = input.attr( 'id' ),
								text = lang( 'Удалить дату' );
							if( !id ){
								input.attr( 'id', id = 'element-' + _.getUnique() );
							}
							if( window.DatePicker && window.$ ){
								new DatePicker(
									window.$( id ),
									{
										'yearOffset'  : dpOffset,
										'format'      : dpformat
									}
								);
							}
							input.attr( 'id', id );
							if( options.button != false ){
								input
								.after(
									'&nbsp;<img style="cursor: pointer;" width="16" height="16" border="0" alt="' + text + '" title="' + text + '" src="media/style/MODxCarbon/images/icons/cal_nodate.gif" onclick="document.getElementById( \'' + id + '\' ).value=\'\';" align="absmiddle"></a>'
								)
							}
							return box
								.data(
									'webElement',
									{
										'type'      :  'date',
										'options'   :  options
									}
								);
						}, // </create
						
						/*
						** @name:
						**   val
						** @path:
						**   jSam -> webElements -> date -> val
						** @description:
						**   Получить/Установить значение web-элемента
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.date.setValue( webElement, value );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @param "value":
						**   String - форматированная дата - новое значение для web-элемента(Необязательно)
						**   Number - timestamp - новое значение для web-элемента(Необязательно)
						** @returns:
						**   Number - TimeStamp
						** @rexample:
						**   jSam.webElements.date.val( $( '[name="longtitle"]' ).parent() );
						**   jSam.webElements.date.val( $( '[name="longtitle"]' ).parent(), '16-05-2002 14:43:00' );
						**   jSam.webElements.date.val( $( '[name="longtitle"]' ).parent(), 715471200000 );
						**   jSam.webElements.date.val( $( '[name="longtitle"]' ).parent(), null );
						*/
						val: function( webElement, value ){
							var input = webElement.children( ':text' ).eq( 0 );
							if( arguments.length > 1 ){
								input.val( _.isNumber( value ) ? _.toDateFormat( value ) : _.isString( value ) ? value : '' );
							}
							value = _.toTimeStamp( input.val() );
							return isNaN( value ) ? 0 : value;
						}, // </val
						
						/*
						** @name:
						**   is
						** @path:
						**   jSam -> webElements -> date -> is
						** @description:
						**   Проверить, является ли web-элемент элементом типа "date"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.date.is( webElement );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @returns:
						**   Boolean
						** @rexample:
						**   jSam.webElements.date.is( $( '[name="longtitle"]' ).parent() );
						*/
						is: function( webElement ){
							var elem = webElement.children( '[name]' )
								.filter( function(){ return this.style.display != 'none' && this.type != 'hidden'; } );
							return elem.length == 1 && elem.is( '.DatePicker:text' );
						} // </is
						
					}, // </date
					
					/*
					** @name:
					**   datepicker
					** @path:
					**   jSam -> webElements -> datepicker
					** @description:
					**   Объект для управления web-элементом типа "datepicker"
					**   Тестовый элемент для выбора даты(jQuery вариация), представляющий из себя контейнер, содержащий DOM-узел <input type="text"> и кнопку вызова виджета
					** @type:
					**   Object
					*/
					'datepicker': {
						
						/*
						** @name:
						**   create
						** @path:
						**   jSam -> webElements -> datepicker -> create
						** @description:
						**   Создать web-элемент типа "datepicker"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.datepicker.create( box, options );
						** @param "options":
						**   Object - Опции web-элемента(*)(**)
						**   * - смотреть функцию jSam.createWebElement
						**   (**) - Дополнительные опции
						**     {
						**       button: Boolean,     // Должна ли присутствовать кнопка удаления даты
						**       settings: Object     // Настройки jQuery UI DatePicker(http://jqueryui.com/demos/datepicker/)
						**     }
						** @returns:
						**   jQuery Object - контейнер - web-элемент
						** @rexample:
						**   jSam.webElements.datepicker.create( $( '[name="longtitle"]' ).parent().empty() );
						**   jSam.webElements.datepicker.create( $( '[name="longtitle"]' ).parent().empty(), { button: false, attr: { style:'color:blue;width:278px;' } } );
						**   jSam.webElements.datepicker.create( $( '[name="longtitle"]' ).parent().empty(), { button: false, attr: { 'class': '', style: '', name: 'longtitle', id: 'longtitle-datepicker' }, settings: { changeMonth: true, changeYear: true, showOtherMonths: true, selectOtherMonths: true } } );
						*/
						create: function( box, options ){
							options = extend(
								true,
								{
									attr: {
										'style': 'width:184px;',
										'class': 'DatePicker UI-DatePicker'
									},
									settings: {
										dayNames: [
											_.lang( 'Воскресенье' ),
											_.lang( 'Понедельник' ),
											_.lang( 'Вторник' ),
											_.lang( 'Среда' ),
											_.lang( 'Четверг' ),
											_.lang( 'Пятница' ),
											_.lang( 'Суббота' )
										],
										dateFormat: _.data.config[ 'datetime_format' ].replace( 'YYYY', 'yy' )
									}
								},
								options || {}
							);
							var
								webElement = jSam.webElements.text.create( box, options ),
								input = webElement.children( ':text' ).eq( 0 ).datepicker( options.settings ),
								text = lang( 'Удалить дату' ),
								id;
							if( options.button != false ){
								id = input.attr( 'id' );
								input
								.after(
									'&nbsp;<img style="cursor: pointer;" width="16" height="16" border="0" alt="' + text + '" title="' + text + '" src="media/style/MODxCarbon/images/icons/cal_nodate.gif" onclick="document.getElementById( \'' + id + '\' ).value=\'\';" align="absmiddle"></a>'
								)
							}
							return box
								.data(
									'webElement',
									{
										'type'      :  'datepicker',
										'options'   :  options
									}
								);
						}, // </create
						
						/*
						** @name:
						**   val
						** @path:
						**   jSam -> webElements -> datepicker -> val
						** @description:
						**   Получить/Установить значение web-элемента
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.datepicker.setValue( webElement, value );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @param "value":
						**   String - форматированная дата - новое значение для web-элемента(Необязательно)
						**   Number - timestamp - новое значение для web-элемента(Необязательно)
						** @returns:
						**   Number - TimeStamp
						** @rexample:
						**   jSam.webElements.datepicker.val( $( '[name="longtitle"]' ).parent() );
						**   jSam.webElements.datepicker.val( $( '[name="longtitle"]' ).parent(), '16-05-2002' );
						**   jSam.webElements.datepicker.val( $( '[name="longtitle"]' ).parent(), 715471200000 );
						**   jSam.webElements.datepicker.val( $( '[name="longtitle"]' ).parent(), null );
						*/
						val: function( webElement, value ){
							var input = webElement.children( ':text' ).eq( 0 );
							if( arguments.length > 1 ){
								input.val( _.isNumber( value ) ? _.toDateFormat( value, true ) : _.isString( value ) ? value : '' );
							}
							value = _.toTimeStamp( input.val() );
							return isNaN( value ) ? 0 : value;
						}, // </val
						
						/*
						** @name:
						**   is
						** @path:
						**   jSam -> webElements -> datepicker -> is
						** @description:
						**   Проверить, является ли web-элемент элементом типа "datepicker"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.datepicker.is( webElement );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @returns:
						**   Boolean
						** @rexample:
						**   jSam.webElements.datepicker.is( $( '[name="longtitle"]' ).parent() );
						*/
						is: function( webElement ){
							var elem = webElement.children( '[name]' )
								.filter( function(){ return this.style.display != 'none' && this.type != 'hidden'; } );
							return elem.length == 1 && elem.is( ':text' ) && !!elem.data( 'datepicker' );
						} // </is
						
					}, // </datepicker
					
					/*
					** @name:
					**   check
					** @path:
					**   jSam -> webElements -> check
					** @description:
					**   Объект для управления web-элементом типа "check"
					**   Элемент-переключатель, представляющий из себя контейнер, содержащий DOM-узел <input type="checkbox"> и оформленный, как тумблер
					** @type:
					**   Object
					*/
					'check': {
						
						/*
						** @name:
						**   create
						** @path:
						**   jSam -> webElements -> check -> create
						** @description:
						**   Создать web-элемент типа "check"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.check.create( box, options );
						** @param "options":
						**   Object - Опции web-элемента(*)
						**   * - смотреть функцию jSam.createWebElement
						** @returns:
						**   jQuery Object - контейнер - web-элемент
						** @rexample:
						**   jSam.webElements.check.create( $( '[name="longtitle"]' ).parent().empty() );
						**   jSam.webElements.check.create( $( '[name="hidemenucheck"]' ).parent().empty(), { attr: { checked: true, name: 'hidemenu' } } );
						*/
						create: function( box, options ){
							options = extend(
								true,
								{
									attr: {
										'type': 'checkbox',
										'onclick': 'this.value = this.checked ? 1 : 0;',
										'id': 'element-' + _.getUnique()
									}
								},
								options || {}
							);
							var
								id = options.attr.id,
								input = $( '<input/>' ).attr( options.attr ),
								label = $( '<label/>' ).attr( 'for', id ),
								checked = input.get( 0 ).checked,
								yes = lang( 'Да' ),
								none = lang( 'Нет' ),
								icon, a;
							if( yes.length > none.length ){
								a = ( ( yes.length - none.length ) * 10 - 10 ).toString().replace( /./g, '&nbsp;' );
								none = a + none + a;
							}
							else if( yes.length < none.length ){
								a = ( ( none.length - yes.length ) * 10 - 10 ).toString().replace( /./g, '&nbsp;' );
								yes = a + yes + a;
							}
							box.append( input, label.html( checked ? yes : none ) );
							input
							.val( checked ? 1 : 0 )
							.button(
								{
									icons: {
										primary: checked ? 'ui-icon-check' : 'ui-icon-closethick'
									}
								}
							)
							.click(
								function(){
									if( this.checked ){
										icon
										.removeClass( 'ui-icon-closethick' )
										.addClass( 'ui-icon-check' )
										.next()
										.html( yes );
									}
									else{
										icon
										.removeClass( 'ui-icon-check' )
										.addClass( 'ui-icon-closethick' )
										.next()
										.html( none );
									}
								}
							);
							icon = label.children( 'span' ).eq( 0 );
							return box
								.data(
									'webElement',
									{
										'type'      :  'check',
										'options'   :  options
									}
								);
						}, // </create
						
						/*
						** @name:
						**   val
						** @path:
						**   jSam -> webElements -> check -> val
						** @description:
						**   Получить/Установить значение web-элемента
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.check.setValue( webElement, value );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @param "value":
						**   Boolean - новое значение для web-элемента(Необязательно)
						** @returns:
						**   Boolean
						** @rexample:
						**   jSam.webElements.check.val( $( '[name="hidemenu"]' ).parent() );
						**   jSam.webElements.check.val( $( '[name="hidemenu"]' ).parent(), true );
						**   jSam.webElements.check.val( $( '[name="hidemenu"]' ).parent(), 1);
						**   jSam.webElements.check.val( $( '[name="hidemenu"]' ).parent(), null );
						**   jSam.webElements.check.val( $( '[name="hidemenu"]' ).parent(), false );
						**   jSam.webElements.check.val( $( '[name="hidemenu"]' ).parent(), 0 );
						*/
						val: function( webElement, value ){
							var input = webElement.children( ':checkbox' ).get( 0 );
							if( arguments.length > 1 ){
								value = !!value;
								if( input.checked != value ){
									input.click();
								}
								else if( input.value != value ? '1' : '0' ){
									input.value = value ? 1 : 0;
								}
							}
							return input.checked ? 1 : 0;
						}, // </val
						
						/*
						** @name:
						**   is
						** @path:
						**   jSam -> webElements -> check -> is
						** @description:
						**   Проверить, является ли web-элемент элементом типа "check"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.check.is( webElement );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @returns:
						**   Boolean
						** @rexample:
						**   jSam.webElements.check.is( $( '[name="longtitle"]' ).parent() );
						*/
						is: function( webElement ){
							var elem = webElement.children( '[name]' )
								.filter( function(){ return this.style.display != 'none' && this.type != 'hidden'; } );
							return elem.length == 1 && elem.is( ':checkbox' ) && elem.next().is( 'label:has( span.ui-icon, span.ui-button-text )' );
						} // </is
						
					}, // </check
					
					/*
					** @name:
					**   autocomplete
					** @path:
					**   jSam -> webElements -> autocomplete
					** @description:
					**   Объект для управления web-элементом типа "autocomplete"
					**   Тестовый элемент с функцией автозавершения значения из возможных значений, представляющий из себя контейнер, содержащий DOM-узел <input type="text">
					** @type:
					**   Object
					*/
					'autocomplete': {
						
						/*
						** @name:
						**   create
						** @path:
						**   jSam -> webElements -> autocomplete -> create
						** @description:
						**   Создать web-элемент типа "autocomplete"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.autocomplete.create( box, options );
						** @param "options":
						**   Object - Опции web-элемента(*)(**)
						**   * - смотреть функцию jSam.createWebElement
						**   (**) - Дополнительные опции
						**     {
						**       button: Boolean,     // Должна ли присутствовать кнопка удаления даты
						**       settings: Object     // Настройки jQuery UI autocomplete(http://jqueryui.com/demos/autocomplete/)
						**     }
						** @returns:
						**   jQuery Object - контейнер - web-элемент
						** @rexample:
						**   jSam.webElements.autocomplete.create( $( '[name="pagetitle"]' ).parent().empty(), { attr:{ name: 'pagetitle' } } );
						**   jSam.webElements.autocomplete.create( $( '[name="longtitle"]' ).parent().empty(), { variants: [ '123', '456' ], attr: { style:'color:blue;' } } );
						**   jSam.webElements.autocomplete.create( $( '[name="longtitle"]' ).parent().empty(), { attr:{ name: 'longtitle' }, variants: [ 'ABC', 'DEF', 'QYZ' ] } );
						*/
						create: function( box, options ){
							options = extend(
								true,
								{
									variants: [],
									attr: {},
									settings: {
										source: []
									}
								},
								options || {}
							);
							if( options.variants.length ){
								options.settings.source = options.settings.source.concat( options.variants );
							}
							var
								webElement = jSam.webElements.text.create( box, options ),
								input = webElement.children( ':text' ).eq( 0 ).autocomplete( options.settings ),
								name = input.attr( 'name' );
							if( options.settings.source.length == 0 && name ){
								input.one(
									'focus',
									function(){
										$.ajax(
											{
												dataType: 'json',
												url: 'index.php',
												data: {
													a: 1000,
													jsam: 11,
													name: name
												},
												success: function( array ){
													input.autocomplete( 'option', 'source', array );
												}
											}
										);
									}
								);
							}
							return box
								.data(
									'webElement',
									{
										'type'      :  'autocomplete',
										'options'   :  options
									}
								);
						}, // </create
						
						/*
						** @name:
						**   val
						** @path:
						**   jSam -> webElements -> autocomplete -> val
						** @description:
						**   Получить/Установить значение web-элемента
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.autocomplete.setValue( webElement, value );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @param "value":
						**   String - новое значение для web-элемента(Необязательно)
						** @returns:
						**   Number - TimeStamp
						** @rexample:
						**   jSam.webElements.autocomplete.val( $( '[name="longtitle"]' ).parent() );
						**   jSam.webElements.autocomplete.val( $( '[name="longtitle"]' ).parent(), 'ABC' );
						*/
						val: function( webElement, value ){
							return _.webElements.text.val.apply( this, arguments );
						}, // </val
						
						/*
						** @name:
						**   is
						** @path:
						**   jSam -> webElements -> autocomplete -> is
						** @description:
						**   Проверить, является ли web-элемент элементом типа "autocomplete"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.autocomplete.is( webElement );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @returns:
						**   Boolean
						** @rexample:
						**   jSam.webElements.autocomplete.is( $( '[name="longtitle"]' ).parent() );
						*/
						is: function( webElement ){
							var elem = webElement.children( '[name]' )
								.filter( function(){ return this.style.display != 'none' && this.type != 'hidden'; } );
							return elem.length == 1 && elem.is( ':text' ) && !!elem.data( 'autocomplete' );
						} // </is
						
					}, // </autocomplete
					
					/*
					** @name:
					**   editor
					** @path:
					**   jSam -> webElements -> editor
					** @description:
					**   Объект для управления web-элементом типа "editor"
					**   Визуальный редактор
					** @type:
					**   Object
					*/
					'editor': {
						
						/*
						** @name:
						**   create
						** @path:
						**   jSam -> webElements -> editor -> create
						** @description:
						**   Создать web-элемент типа "editor"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.editor.create( box, options );
						** @param "options":
						**   Object - Опции web-элемента(*)(**)
						**   (*) - смотреть функцию jSam.createWebElement
						**   (**) - Дополнительные опции
						**     {
						**       type: String,        // Тип визуального редактора
						**       settings: Object     // Настройки визуального редактора
						**     }
						** @returns:
						**   jQuery Object - контейнер - web-элемент
						** @rexample:
						**   jSam.webElements.editor.create( $( '[name="longtitle"]' ).parent().empty(), {} );
						**   jSam.webElements.editor.create( $( '[name="longtitle"]' ).parent().empty(), { type: 'CKEditor' } );
						**   jSam.webElements.editor.create( $( '[name="longtitle"]' ).parent().empty(), { type: 'tinyMCE', settings: {} } );
						*/
						create: function( box, options ){
							var textarea = jSam.webElements.textarea.create.apply( this, arguments ).children( 'textarea' ).eq( 0 );
							_.createEditor( textarea, options.type, options.settings );
							return box
								.data(
									'webElement',
									{
										'type'      :  'editor',
										'options'   :  options
									}
								);
						}, // </create
						
						/*
						** @name:
						**   val
						** @path:
						**   jSam -> webElements -> editor -> val
						** @description:
						**   Получить/Установить значение web-элемента
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.editor.val( webElement, value );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @param "value":
						**   String - новое значение для web-элемента(Необязательно)
						** @returns:
						**   String - значение элемента
						** @rexample:
						**   jSam.webElements.editor.val( $( '#ta' ).parent() );
						**   jSam.webElements.editor.val( $( '#ta' ).parent(), "&nbsp;&nbsp;Multi...<br>&nbsp;&nbsp;...line" );
						*/
						val: function( webElement, value ){
							arguments[ 0 ] = webElement.children( 'textarea' ).eq( 0 );
							return _.editorValue.apply( this, arguments );
						}, // </val
						
						/*
						** @name:
						**   is
						** @path:
						**   jSam -> webElements -> editor -> is
						** @description:
						**   Проверить, является ли web-элемент элементом типа "editor"
						** @type:
						**   Function
						** @api:
						**   jSam.webElements.editor.is( webElement );
						** @param "webElement":
						**   jQuery Object - контейнер - web-элемент
						** @returns:
						**   Boolean
						** @rexample:
						**   jSam.webElements.editor.is( $( '#ta' ).parent() );
						**   jSam.webElements.editor.is( $( '[name="introtext"]' ).parent() );
						*/
						is: function( webElement ){
							var elem = webElement.children( 'input, textarea' ).eq( 0 );
							return elem.length && !!_.detectEditor( elem );
						} // </is
						
					} // </editor
					
				}, // </webElements
				
				/*
				** @name:
				**   editors
				** @path:
				**   jSam -> editors
				** @description:
				**   Коллекция объектов для управления редакторами текста
				** @type:
				**   Object
				*/
				'editors': {
					
					/*
					** @name:
					**   tinymce
					** @path:
					**   jSam -> editors -> tinymce
					** @description:
					**   Объект для управления визуальным редактором tinyMCE
					** @type:
					**   Object
					*/
					'tinymce': {
						
						/*
						** @name:
						**   init
						** @path:
						**   jSam -> editors -> tinymce -> init
						** @description:
						**   Создать визуальный редактор tinyMCE
						** @type:
						**   Function
						** @api:
						**   jSam.editors.tinymce.init( textarea, options );
						** @param "textarea":
						**   DOM Node
						** @param "options":
						**   Object - Опции визуального редактора
						** @returns:
						**   Null
						** @example:
						**   jSam.editors.tinymce.init( $( '[name="introtext"]' ).attr( 'id', 'introtext' ).get( 0 ), { theme: 'simple', mode: 'exact' } );
						**   jSam.editors.tinymce.init( $( '[name="introtext"]' ).attr( 'id', 'introtext' ).get( 0 ), { theme: 'advanced', mode: 'exact', width: '450px', height: '130px' } );
						*/
						init: function( textarea, options ){
							options.elements = textarea.id;
							window.tinyMCE.init( options );
						}, // </init
						
						/*
						** @name:
						**   destroy
						** @path:
						**   jSam -> editors -> tinymce -> destroy
						** @description:
						**   Удалить визуальный редактор tinyMCE
						** @type:
						**   Function
						** @api:
						**   jSam.editors.tinymce.destroy( textarea );
						** @param "textarea":
						**   DOM Node
						** @returns:
						**   Boolean - статус удаления редактора
						** @example:
						**   jSam.editors.tinymce.destroy( document.getElementById( 'ta' ) );
						*/
						destroy: function( textarea ){
							return window.tinyMCE.get( textarea.id ).remove();
						}, // </destroy
						
						/*
						** @name:
						**   val
						** @path:
						**   jSam -> editors -> tinymce -> val
						** @description:
						**   Назначить/Получить значение визуального редактора tinyMCE
						** @type:
						**   Function
						** @api:
						**   jSam.editors.tinymce.val( textarea, value );
						** @param "textarea":
						**   DOM Node
						** @param "value":
						**   String - новое значение редактора
						** @returns:
						**   String - значение редактора
						** @example:
						**   jSam.editors.tinymce.val( document.getElementById( 'ta' ) );
						**   jSam.editors.tinymce.val( document.getElementById( 'ta' ), 'ABC<br><b>XYZ</b>' );
						*/
						val: function( textarea, value ){
							var api = window.tinyMCE.get( textarea.id );
							if( arguments.length > 1 ){
								api.setContent( value.toString() );
							}
							return api.getContent();
						}, // </val
						
						/*
						** @name:
						**   is
						** @path:
						**   jSam -> editors -> tinymce -> is
						** @description:
						**   Проверить, является ли textarea визуальным редактором tinyMCE
						** @type:
						**   Function
						** @api:
						**   jSam.editors.tinymce.is( textarea );
						** @param "textarea":
						**   DOM Node
						** @returns:
						**   Boolean
						** @example:
						**   jSam.editors.tinymce.is( $( '#ta' ).get( 0 ) );
						*/
						is: function( textarea ){
							return !!window.tinyMCE.get( textarea.id );
						}, // </is
						
						/*
						** @name:
						**   object
						** @path:
						**   jSam -> editors -> tinymce -> object
						** @description:
						**   Название глобального объекта визуального редактора tinyMCE
						** @type:
						**   Object
						*/
						object: 'tinyMCE',
						
						/*
						** @name:
						**   options
						** @path:
						**   jSam -> editors -> tinymce -> options
						** @description:
						**   Опции по умолчанию визуального редактора tinyMCE
						** @type:
						**   Object
						*/
						options: {
							theme                            : 'advanced',
							mode                             : 'exact',
							elements                         : 'ta,tv1',
							width                            : '100%',
							height                           : '400',
							language                         : '',
							document_base_url                : url.site_url,
							relative_urls                    : true,
							remove_script_host               : true,
							convert_urls                     : true,
							forced_root_block                : 'p',
							force_p_newlines                 : true,
							valid_elements                   : '@[id|class|style|title|dir<ltr?rtl|lang|xml::lang|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],a[rel|rev|charset|hreflang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur],strong/b,em/i,strike,u,#p[align],-ol[type|compact],-ul[type|compact],-li,br,img[longdesc|usemap|src|border|alt=|title|hspace|vspace|width|height|align],-sub,-sup,-blockquote,-table[border=0|cellspacing|cellpadding|width|frame|rules|height|align|summary|bgcolor|background|bordercolor],-tr[rowspan|width|height|align|valign|bgcolor|background|bordercolor],tbody,thead,tfoot,#td[colspan|rowspan|width|height|align|valign|bgcolor|background|bordercolor|scope],#th[colspan|rowspan|width|height|align|valign|scope],caption,-div,-span,-code,-pre,address,-h1,-h2,-h3,-h4,-h5,-h6,hr[size|noshade],-font[face|size|color],dd,dl,dt,cite,abbr,acronym,del[datetime|cite],ins[datetime|cite],object[classid|width|height|codebase|*],param[name|value|_value],embed[type|width|height|src|*],script[src|type],map[name],area[shape|coords|href|alt|target],bdo,button,col[align|char|charoff|span|valign|width],colgroup[align|char|charoff|span|valign|width],dfn,fieldset,form[action|accept|accept-charset|enctype|method],input[accept|alt|checked|disabled|maxlength|name|readonly|size|src|type|value],kbd,label[for],legend,noscript,optgroup[label|disabled],option[disabled|label|selected|value],q[cite],samp,select[disabled|multiple|name|size],small,textarea[cols|rows|disabled|name|readonly],tt,var,big',
							extended_valid_elements          : '',
							invalid_elements                 : '',
							popup_css_add                    : url.base_url + 'assets/plugins/tinymce/style/popup_add.css',
							accessibility_warnings           : false,
							theme_advanced_toolbar_location  : 'top',
							theme_advanced_statusbar_location: 'bottom',
							theme_advanced_toolbar_align     : 'ltr',
							theme_advanced_font_sizes        : '80%,90%,100%,120%,140%,160%,180%,220%,260%,320%,400%,500%,700%',
							content_css                      : url.base_url + 'assets/plugins/tinymce/style/content.css',
							formats                          : {
								alignleft: {
									selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img',
									classes: 'justifyleft'
								},
								alignright: {
									selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img',
									classes: 'justifyright'
								},
								alignfull: {
									selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img',
									classes: 'justifyfull'
								}
							},
							apply_source_formatting          : true,
							remove_linebreaks                : false,
							convert_fonts_to_spans           : true,
							plugins                          : 'save,advlist,clearfloat,style,fullscreen,advimage,paste,advlink,media,contextmenu,table',
							theme_advanced_buttons1          : 'undo,redo,|,bold,forecolor,backcolor,strikethrough,formatselect,fontsizeselect,pastetext,pasteword,code,|,fullscreen,help',
							theme_advanced_buttons2          : 'image,media,link,unlink,anchor,|,justifyleft,justifycenter,justifyright,clearfloat,|,bullist,numlist,|,blockquote,outdent,indent,|,table,hr,|,styleprops,removeformat',
							theme_advanced_buttons3          : '',
							theme_advanced_buttons4          : '',
							theme_advanced_resize_horizontal :  false,
							external_link_list_url           : url.base_url + 'assets/plugins/tinymce/inc/tinymce.linklist.php',
							theme_advanced_blockformats      : 'p,h2,h3,h4,h5,h6,div,blockquote,code,pre',
							theme_advanced_styles            : '',
							theme_advanced_disable           : '',
							theme_advanced_resizing          : true,
							fullscreen_settings : {
								theme_advanced_buttons1_add_before : 'save'
							},
							plugin_insertdate_dateFormat     : '%d-%m-%Y',
							plugin_insertdate_timeFormat     : '%H:%M:%S',
							entity_encoding                  : 'named',
							file_browser_callback            : 'modx_fb',
							onchange_callback                : false
						} // </options
						
					}, // </tinymce
					
					/*
					** @name:
					**   ckeditor
					** @path:
					**   jSam -> editors -> ckeditor
					** @description:
					**   Объект для управления визуальным редактором CKEditor
					** @type:
					**   Object
					*/
					'ckeditor': {
						
						/*
						** @name:
						**   init
						** @path:
						**   jSam -> editors -> ckeditor -> init
						** @description:
						**   Создать визуальный редактор CKEditor
						** @type:
						**   Function
						** @api:
						**   jSam.editors.ckeditor.init( textarea, options );
						** @param "textarea":
						**   DOM Node
						** @param "options":
						**   Object - Опции визуального редактора
						** @returns:
						**   Null
						** @example:
						**   jSam.editors.ckeditor.init( $( '[name="introtext"]' ).attr( 'id', 'introtext' ).get( 0 ), { theme: 'simple', mode: 'exact' } );
						**   jSam.editors.ckeditor.init( $( '[name="introtext"]' ).attr( 'id', 'introtext' ).get( 0 ), { theme: 'advanced', mode: 'exact', width: '450px', height: '130px' } );
						*/
						init: function( textarea, options ){
							window.CKEDITOR.replace( textarea.id, options );
						}, // </init
						
						/*
						** @name:
						**   destroy
						** @path:
						**   jSam -> editors -> ckeditor -> destroy
						** @description:
						**   Удалить визуальный редактор CKEditor
						** @type:
						**   Function
						** @api:
						**   jSam.editors.ckeditor.destroy( textarea );
						** @param "textarea":
						**   DOM Node
						** @returns:
						**   Boolean - статус удаления редактора
						** @example:
						**   jSam.editors.ckeditor.destroy( $( '#ta' ).get( 0 ) );
						*/
						destroy: function( textarea ){
							return window.CKEDITOR.instances[ textarea.id ].destroy();
						}, // </destroy
						
						/*
						** @name:
						**   val
						** @path:
						**   jSam -> editors -> ckeditor -> val
						** @description:
						**   Назначить/Получить значение визуального редактора CKEditor
						** @type:
						**   Function
						** @api:
						**   jSam.editors.ckeditor.val( textarea, value );
						** @param "textarea":
						**   DOM Node
						** @param "value":
						**   String - новое значение редактора
						** @returns:
						**   String - значение редактора
						** @example:
						**   jSam.editors.ckeditor.val( $( '#ta' ).get( 0 ) );
						**   jSam.editors.ckeditor.val( $( '#ta' ).get( 0 ), 'ABC<br><b>XYZ</b>' );
						*/
						val: function( textarea, value ){
							var api = window.CKEDITOR.instances[ textarea.id ];
							if( arguments.length > 1 ){
								api.setData( value.toString() );
							}
							return api.getData();
						}, // </val
						
						/*
						** @name:
						**   is
						** @path:
						**   jSam -> editors -> ckeditor -> is
						** @description:
						**   Проверить, является ли textarea визуальным редактором CKEditor
						** @type:
						**   Function
						** @api:
						**   jSam.editors.ckeditor.is( textarea );
						** @param "textarea":
						**   DOM Node
						** @returns:
						**   Boolean
						** @example:
						**   jSam.editors.ckeditor.is( $( '#ta' ).get( 0 ) );
						*/
						is: function( textarea ){
							return !!window.CKEDITOR.instances[ textarea.id ];
						}, // </is
						
						/*
						** @name:
						**   object
						** @path:
						**   jSam -> editors -> ckeditor -> object
						** @description:
						**   Название глобального объекта визуального редактора CKEditor
						** @type:
						**   Object
						*/
						object: 'CKEDITOR',
						
						/*
						** @name:
						**   options
						** @path:
						**   jSam -> editors -> ckeditor -> options
						** @description:
						**   Опции по умолчанию визуального редактора CKEditor
						** @type:
						**   Object
						*/
						options: {
							autoUpdateElement: true,
							baseHref: url.site_url,
							contentsCss: url.jsam_extensions_url + "CKEditor/ckeditor/contents.css",
							contentsLangDirection: "ltr",
							language: "",
							defaultLanguage: "en",
							enterMode: 1,
							shiftEnterMode: 2,
							corePlugins: "",
							docType: "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">",
							bodyId: "",
							bodyClass: "",
							fullPage: false,
							height: 200,
							plugins: "about,a11yhelp,basicstyles,blockquote,button,clipboard,colorbutton,colordialog,contextmenu,div,elementspath,enterkey,entities,filebrowser,find,flash,font,format,forms,horizontalrule,htmldataprocessor,image,indent,justify,keystrokes,link,list,maximize,newpage,pagebreak,pastefromword,pastetext,popup,preview,print,removeformat,resize,save,scayt,smiley,showblocks,showborders,sourcearea,stylescombo,table,tabletools,specialchar,tab,templates,toolbar,undo,wysiwygarea,wsc",
							extraPlugins: "",
							removePlugins: "",
							protectedSource: [],
							tabIndex: 0,
							theme: "default",
							skin: "kama",
							width: "",
							baseFloatZIndex: 10000,
							coreStyles_bold: {
								element: "strong",
								overrides: "b"
							},
							coreStyles_italic: {
								element: "em",
								overrides: "i"
							},
							coreStyles_underline: {
								element: "ins"
							},
							coreStyles_strike: {
								element: "del"
							},
							coreStyles_subscript: {
								element: "sub"
							},
							coreStyles_superscript: {
								element: "sup"
							},
							colorButton_enableMore: true,
							colorButton_colors: "000,800000,8B4513,2F4F4F,008080,000080,4B0082,696969,B22222,A52A2A,DAA520,006400,40E0D0,0000CD,800080,808080,F00,FF8C00,FFD700,008000,0FF,00F,EE82EE,A9A9A9,FFA07A,FFA500,FFFF00,00FF00,AFEEEE,ADD8E6,DDA0DD,D3D3D3,FFF0F5,FAEBD7,FFFFE0,F0FFF0,F0FFFF,F0F8FF,E6E6FA,FFF",
							colorButton_foreStyle: {
								element: "span",
								styles: {
									color: "#(color)"
								},
								overrides: [
									{
										element: "font",
										attributes: {
											color: null
										}
									}
								],
								childRule: function( l ){
									return l.getName() != "a";
								}
							},
							colorButton_backStyle: {
								element: "span",
								styles: {
									'background-color': "#(color)"
								}
							},
							entities: true,
							entities_latin: true,
							entities_greek: true,
							entities_processNumerical: false,
							entities_additional: "#39",
							find_highlight: {
								element: "span",
								styles: {
									'background-color': "#004",
									color: "#fff"
								}
							},
							flashEmbedTagOnly: false,
							flashAddEmbedTag: true,
							flashConvertOnEdit: false,
							font_names: "Arial/Arial, Helvetica, sans-serif;Comic Sans MS/Comic Sans MS, cursive;Courier New/Courier New, Courier, monospace;Georgia/Georgia, serif;Lucida Sans Unicode/Lucida Sans Unicode, Lucida Grande, sans-serif;Tahoma/Tahoma, Geneva, sans-serif;Times New Roman/Times New Roman, Times, serif;Trebuchet MS/Trebuchet MS, Helvetica, sans-serif;Verdana/Verdana, Geneva, sans-serif",
							font_defaultLabel: "",
							font_style: {
								element: "span",
								styles: {
									'font-family': "#(family)"
								},
								overrides: [
									{
										element: "font",
										attributes: {
											face: null
										}
									}
								]
							},
							fontSize_sizes: "80%/80%;90%/90%;100%/100%;120%/120%;140%/140%;160%/160%;180%/180%;200%/200%;240%/240%;280%/280%;320%/320%;400%/400%;500%/500%",
							fontSize_defaultLabel: "",
							fontSize_style: {
								element: "span",
								styles: {
									'font-size': "#(size)"
								},
								overrides: [
									{
										element: "font",
										attributes: {
											size: null
										}
									}
								]
							},
							format_tags: "p;h1;h2;h3;h4;h5;h6;pre;address;div",
							format_p: {
								element: "p",
								_ST: "",
								_AC: {
									_length: 0
								}
							},
							format_div: {
								element: "div"
							},
							format_pre: {
								element: "pre"
							},
							format_address: {
								element: "address"
							},
							format_h1: {
								element: "h1"
							},
							format_h2: {
								element: "h2"
							},
							format_h3: {
								element: "h3"
							},
							format_h4: {
								element: "h4"
							},
							format_h5: {
								element: "h5"
							},
							format_h6: {
								element: "h6"
							},
							forceSimpleAmpersand: false,
							image_removeLinkByEmptyURL: true,
							indentOffset: 40,
							indentUnit: "px",
							indentClasses: null,
							justifyClasses: null,
							blockedKeystrokes: [
								1066,
								1073,
								1085
							],
							keystrokes: [
								[
									4121,
									"toolbarFocus"
								],
								[
									4122,
									"elementsPathFocus"
								],
								[
									2121,
									"contextMenu"
								],
								[
									3121,
									"contextMenu"
								],
								[
									1090,
									"undo"
								],
								[
									1089,
									"redo"
								],
								[
									3090,
									"redo"
								],
								[
									1076,
									"link"
								],
								[
									1066,
									"bold"
								],
								[
									1073,
									"italic"
								],
								[
									1085,
									"underline"
								],
								[
									4109,
									"toolbarCollapse"
								],
								[
									4048,
									"a11yHelp"
								]
							],
							linkShowAdvancedTab: true,
							linkShowTargetTab: true,
							newpage_html: "",
							removeFormatTags: "b,big,code,del,dfn,em,font,i,ins,kbd,q,samp,small,span,strike,strong,sub,sup,tt,u,var",
							removeFormatAttributes: "class,style,lang,width,height,align,hspace,valign",
							resize_minWidth: 750,
							resize_minHeight: 250,
							resize_maxWidth: 3000,
							resize_maxHeight: 3000,
							resize_enabled: true,
							smiley_path: url.site_url.replace( /\/$/, '' ) + url.jsam_extensions_url + "CKEditor/ckeditor/plugins/smiley/images/",
							smiley_images: [
								"regular_smile.gif",
								"sad_smile.gif",
								"wink_smile.gif",
								"teeth_smile.gif",
								"confused_smile.gif",
								"tounge_smile.gif",
								"embaressed_smile.gif",
								"omg_smile.gif",
								"whatchutalkingabout_smile.gif",
								"angry_smile.gif",
								"angel_smile.gif",
								"shades_smile.gif",
								"devil_smile.gif",
								"cry_smile.gif",
								"lightbulb.gif",
								"thumbs_down.gif",
								"thumbs_up.gif",
								"heart.gif",
								"broken_heart.gif",
								"kiss.gif",
								"envelope.gif"
							],
							smiley_descriptions: [
								"smiley",
								"sad",
								"wink",
								"laugh",
								"frown",
								"cheeky",
								"blush",
								"surprise",
								"indecision",
								"angry",
								"angle",
								"cool",
								"devil",
								"crying",
								"enlightened",
								"no",
								"yes",
								"heart",
								"broken heart",
								"kiss",
								"mail"
							],
							startupOutlineBlocks: false,
							stylesCombo_stylesSet: "default",
							templates: "default",
							templates_files: [
								url.jsam_extensions_url + "CKEditor/ckeditor/plugins/templates/templates/default.js?t=A1QD"
							],
							templates_replaceContent: true,
							toolbarLocation: "top",
							toolbarCanCollapse: true,
							undoStackSize: 20,
							disableObjectResizing: false,
							disableNativeTableHandles: true,
							disableNativeSpellChecker: true,
							ignoreEmptyParagraph: true,
							wsc_customerId: "1:ua3xw1-2XyGJ3-GWruD3-6OFNT1-oXcuB1-nR6Bp4-hgQHc-EcYng3-sdRXG3-NOfFk",
							wsc_customLoaderScript: null,
							menu_subMenuDelay: 400,
							menu_groups: "clipboard,form,tablecell,tablecellproperties,tablerow,tablecolumn,table,anchor,link,image,flash,checkbox,radio,textfield,hiddenfield,imagebutton,button,select,textarea,div",
							startupMode: "wysiwyg",
							startupFocus: false,
							editingBlock: true,
							dialog_backgroundCoverColor: "rgb(55,55,55)",
							filebrowserBrowseUrl: url.base_url + "manager/media/browser/mcpuk/browser.php?Connector=" + url.base_url + "manager/media/browser/mcpuk/connectors/php/connector.php&ServerPath=/&editor=tinymce3&editorpath=" + url.jsam_extensions_url + "CKEditor/",
							filebrowserImageBrowseUrl: url.base_url + "manager/media/browser/mcpuk/browser.php?Connector=" + url.base_url + "manager/media/browser/mcpuk/connectors/php/connector.php&ServerPath=/&editor=tinymce3&editorpath=" + url.jsam_extensions_url + "CKEditor/&Type=images",
							filebrowserFlashBrowseUrl: url.base_url + "manager/media/browser/mcpuk/browser.php?Connector=" + url.base_url + "manager/media/browser/mcpuk/connectors/php/connector.php&ServerPath=/&editor=tinymce3&editorpath=" + url.jsam_extensions_url + "CKEditor/&Type=flash",
							toolbar: "Simple",
							toolbar_Basic: [
								[
									"Bold",
									"Italic",
									"-",
									"NumberedList",
									"BulletedList",
									"-",
									"Link",
									"Unlink",
									"-",
									"About"
								]
							],
							toolbar_Simple: [
								[
									"Source"
								],
								[
									"Bold",
									"Italic",
									"Underline",
									"Strike"
								],
								[
									"TextColor",
									"BGColor"
								],
								[
									"JustifyLeft",
									"JustifyCenter",
									"JustifyRight"
								],
								[
									"Link",
									"Unlink"
								],
								[
									"Image",
									"Smiley"
								],
								[
									"HorizontalRule"
								],
								[
									"About"
								]
							],
							toolbar_Full: [
								[
									"Source",
									"-",
									"Save",
									"NewPage",
									"Preview",
									"-",
									"Templates"
								],
								[
									"Cut",
									"Copy",
									"Paste",
									"PasteText",
									"PasteFromWord",
									"-",
									"Print",
									"SpellChecker",
									"Scayt"
								],
								[
									"Undo",
									"Redo",
									"-",
									"Find",
									"Replace",
									"-",
									"SelectAll",
									"RemoveFormat"
								],
								[
									"Form",
									"Checkbox",
									"Radio",
									"TextField",
									"Textarea",
									"Select",
									"Button",
									"ImageButton",
									"HiddenField"
								],
								"/",
								[
									"Bold",
									"Italic",
									"Underline",
									"Strike",
									"-",
									"Subscript",
									"Superscript"
								],
								[
									"NumberedList",
									"BulletedList",
									"-",
									"Outdent",
									"Indent",
									"Blockquote",
									"CreateDiv"
								],
								[
									"JustifyLeft",
									"JustifyCenter",
									"JustifyRight",
									"JustifyBlock"
								],
								[
									"Link",
									"Unlink",
									"Anchor"
								],
								[
									"Image",
									"Flash",
									"Table",
									"HorizontalRule",
									"Smiley",
									"SpecialChar",
									"PageBreak"
								],
								"/",
								[
									"Styles",
									"Format",
									"Font",
									"FontSize"
								],
								[
									"TextColor",
									"BGColor"
								],
								[
									"Maximize",
									"ShowBlocks",
									"-",
									"About"
								]
							],
							toolbar_MODx: [
								[
									"Source"
								],
								[
									"Bold",
									"Italic",
									"Underline",
									"Strike",
									"-",
									"Subscript",
									"Superscript"
								],
								[
									"PasteText",
									"PasteFromWord"
								],
								[
									"Undo",
									"Redo",
									"-",
									"Find",
									"-",
									"RemoveFormat"
								],
								"/",
								[
									"NumberedList",
									"BulletedList",
									"-",
									"Outdent",
									"Indent",
									"Blockquote"
								],
								[
									"JustifyLeft",
									"JustifyCenter",
									"JustifyRight"
								],
								[
									"Link",
									"Unlink",
									"Anchor"
								],
								[
									"Image",
									"Flash",
									"Table",
									"HorizontalRule",
									"Smiley",
									"SpecialChar"
								],
								"/",
								[
									"Format",
									"Font",
									"FontSize"
								],
								[
									"TextColor",
									"BGColor"
								],
								[
									"Maximize",
									"ShowBlocks",
									"-",
									"About"
								]
							]
						} // </options
						
					} // </ckeditor
					
				}, // </editors
				
				/*
				** @name:
				**   ui
				** @path:
				**   jSam -> ui
				** @description:
				**   Объект функций для создания UI-элементов
				** @type:
				**   Object
				*/
				'ui': {
					
					/*
					** @name:
					**   help
					** @path:
					**   jSam -> ui -> help
					** @api:
					**   jSam.ui.help( text );
					** @param "text":
					**   Текст подсказки
					** @description:
					**   Создать всплывающую подсказку
					** @type:
					**   Function
					** @returns:
					**   jQuery Object
					*/
					help: function( text ){
						text = _.isNumberOrString( text ) ? text : '';
						var img = $(
							'<img/>',
							{
								'title' : text,
								'alt'   : text,
								'src'   : 'media/style/MODxCarbon/images/icons/b02_trans.gif',
								'class' : 'tooltip',
								'css'   : {
									'cursor': 'help'
								}
							}
						);
						if( window.ie6 || !window.Tips ){
							img.attr(
								{
									'onmouseover': "this.src='media/style/MODxCarbon/images/icons/b02.gif';",
									'onmouseout': "this.src='media/style/MODxCarbon/images/icons/b02_trans.gif';",
									'onclick': "alert(this.alt);"
								}
							);
						}
						else{
							new Tips( img[ 0 ], { className: 'custom' } );
						}
						return img;
					} // </help
					
				}, // </ui
				
				
				/***********************************/
				/***** Объекты рабочих классов *****/
				/***********************************/
				
				
				/*
				** @name:
				**   classes
				** @path:
				**   jSam -> classes
				** @description:
				**   Объект классов
				** @type:
				**   Object
				*/
				classes: {
					
					/*
					** @name:
					**   field
					** @path:
					**   jSam -> classes -> field
					** @description:
					**   Класс для работы с полями в контейнере context
					**   Рабочим экземпляром класса является jSam.field и дальнейшие примеры использования будут идти с ним
					** @type:
					**   Function
					** @api:
					**   new jSam.classes.field( context, tab );
					** @param "context":
					**   jQuery Object - контейнер, в котором находятся поля
					** @param "tab":
					**   Object - объект управления табами
					** @returns:
					**   Object - экземпляр класса
					** @workingCopy:
					**   jSam -> field
					** @example:
					**   new jSam.classes.field( $( '#documentPane' ), _.tab );
					*/
					field: extend(
						function( context, tab ){
							if( _.isDOM( context ) ){
								context = $( context );
							}
							if( !_.is$( context ) ){
								context = _.form;
							}
							this.context = context;
							this.tab = tab || _.tab;
						},
						{
							prototype: {
								
								/*
								** @name:
								**   get
								** @path:
								**   jSam -> field -> get
								** @api:
								**   jSam.field.get( query );
								** @description:
								**   Получить поле(поля)
								** @type:
								**   Function
								** @param "query":
								**   String - имя webElement`a в нижнем регистре в чистом виде(пример 'pagetitle')
								**   String - текущее название поля(пример 'Заголовок')
								**   DOM node - DOM-узел HTMLTableRowElement - тег tr
								**   jQuery Object - DOM-узел HTMLTableRowElement - тег tr
								**   Array - массив возможных значений - [ Number, String, String, DOM node, jQuery Object, Array ]
								**   Если данный параметр не указан при выполнении функции или равен null - функция возвращает все поля
								** @returns:
								**   jQuery Object - DOM-узлы HTMLTableRowElement - набор полей
								** @example:
								**   jSam.field.get();                    // Все поля
								**   jSam.field.get( null );              // Все поля
								**   jSam.field.get( 'longtitle' );       // Поле "Расширенный заголовок"
								**   jSam.field.get( 'tv1' );             // Поле - TV параметр с ID=1
								**   jSam.field.get( 'Описание' );        // Поле "Описание"
								**   jSam.field.get( $( 'tr#myTR' ) );
								**   jSam.field.get( [ 'longtitle', 'Описание', 'Содержимое ресурса' ] ); // "Расширенный заголовок", "Описание" и "Содержимое ресурса"
								*/
								get: (
									function(){
										var elementName = /^[a-z0-9_-]+$/;
										return function( query ){
											
											// Quick selection
											if( arguments.length == 1 ){
												if( typeof query == 'string' && elementName.test( query ) ){
													return this.getForName( query );
												}
												else if( _.is$( query ) ){
													return query;
												}
											}
											
											var
												array = [],
												api = this,
												containers;
											
											if( arguments.length == 0 || query == null || typeof query == 'undefined' ){
												elements = this.context.find( '[name][type!="hidden"]:not( option )' )
												.foreach(
													function(){
														var
															parent = this.parent(),
															_parent = parent.parent(),
															prev = parent.prev(),
															element;
														if( parent.is( 'td' ) ){
															element = _parent;
														}
														else if( !parent.is( 'fieldset, form' ) && !_parent.is( '.actionButtons' ) ){
															if( parent.is( '.sectionBody' ) ){
																if( !_parent.is( 'fieldset, form' ) ){
																	element = _parent.is( 'td' ) ? _parent.parent() : _parent;
																}
															}
															else{
																element = parent;
															}
														}
														if( element && element.length && $.inArray( element = element.get( 0 ), array ) == -1 ){
															array.push( element );
														}
													}
												);
												return $( array );
											}
											
											query = _.toInlineArray( arguments );
											
											foreach(
												query,
												function( elem ){
													if( _.isString( elem ) ){
														elem = elem.toString();
														if( elementName.test( elem ) ){
															array.push( api.getForName( elem ).get() )
														}
														else{
															if( !containers ){
																containers = api.context.find( 'td, .sectionHeader' );
															}
															containers
															.foreach(
																function(){
																	var
																		name = this,
																		span = this.children( 'span.warning' ).eq( 0 ),
																		parent = this.parent(),
																		isSection = this.is( '.sectionHeader' ),
																		container;
																	if( ( span.length ? span : this ).text().trim() == elem ){
																		if( isSection ){
																			if( parent.is( 'td' ) ){
																				container = parent.parent();
																			}
																			else if( parent.children().length == 2 ){
																				container = parent;
																			}
																			else if( ( parent = this.next() ).is( '.sectionBody' ) ){
																				container = parent;
																			}
																		}
																		else{
																			container = parent;
																		}
																		array.push( container.get() );
																	}
																}
															);
														}
													}
													else if( _.isDOM( elem ) ){
														array.push( elem );
													}
													else if( _.is$( elem ) ){
														array.push( elem.get() );
													}
												}
											);
											
											return $( _.toInlineArray( array ) );
											
										};
									}
								)(), // </get
								
								/*
								** @name:
								**   getForName
								** @path:
								**   jSam -> field -> getForName
								** @description:
								**   Получить поле(также поле TV параметра) по его реальному имени
								** @type:
								**   Function
								** @api:
								**   jSam.field.getForName( name );
								** @param "name":
								**   Название поля или TV-параметра
								** @returns:
								**   jQuery Object - DOM-узлы HTMLTableRowElement - набор полей
								** @example:
								**   jSam.field.getForName( 'ta' );
								**   jSam.field.getForName( 'pagetitle' );
								**   jSam.field.getForName( 'tv4' );
								**   jSam.field.getForName( 'tmpl_name_45' );
								*/
								getForName: function( name ){
									var
										element = this.context.find( '[name="' + ( _.isNumberOrString( _.data.TV[ name ] ) ? 'tv' + _.data.TV[ name ] : name ) + '"]' ).eq( 0 ),
										parent = element.parent(),
										parentParent = parent.parent();
									if( !element.length ){
										return a;
									}
									else if( parentParent.is( 'tr' ) ){
										return parentParent;
									}
									else if( parent.is( '.sectionBody' ) && !parentParent.is( 'fieldset, form' ) ){
										return parentParent.is( 'td' ) ? parentParent.parent() : parentParent;
									}
									else if( !parent.is( 'fieldset, form' ) ){
										return parent;
									}
									return a;
								}, // </getForName
								
								/*
								** @name:
								**   info
								** @path:
								**   jSam -> field -> info
								** @description:
								**   Получить информацияю по полю(полям)
								** @type:
								**   Function
								** @api:
								**   jSam.field.info( query );
								** @param "query":
								**   Запрос полей по правилам функции field.get
								** @returns:
								**   jQuery Object - Array
								** @example:
								**   jSam.field.info( 'ta' );
								**   jSam.field.info( [ 'pagetitle', 'Описание' ] );
								*/
								info: function( query ){
									return this.get( query ).map(
										function(){
											var
												type = 'noname',
												field = $( this ),
												webElement = field,
												name = a,
												children = field.children(),
												temp;
											if( field.is( 'tr' ) ){
												if( children.length == 2 ){
													name = children.eq( 0 );
													webElement = children.eq( 1 );
													type = 'inline';
												}
												else if( children.length == 1 ){
													temp = children.children().eq( 0 );
													if( temp.is( '.sectionHeader' ) ){
														name = temp;
														temp = temp.next();
														if( temp.is( '.sectionBody' ) ){
															webElement = temp;
															type = 'box';
														}
													}
												}
											}
											if( name.is( 'td' ) ){
												temp = name.children().eq( 0 );
												if( temp.is( '.warning' ) || ( name.is( '.warning' ) && temp.is( 'b' ) ) ){
													name = temp;
												}
											}
											return {
												type: type,
												field: field,
												webElement: webElement,
												webElementType: _.detectWebElement( webElement ),
												name: name,
												children: children
											};
										}
									);
								}, // </info
								
								/*
								** @name:
								**   rename
								** @path:
								**   jSam -> field -> rename
								** @description:
								**   Переименовать поле(поля)
								** @type:
								**   Function
								** @api:
								**   jSam.field.rename( query, text );
								** @param "query":
								**   Запрос полей по правилам функции field.get
								** @param "text":
								**   String - Новое название поля
								** @returns:
								**   jQuery Object - Array - информационный массив полей
								** @example:
								**   jSam.field.rename( 'ta', 'Контент' );
								**   jSam.field.rename( [ 'pagetitle', 'Описание' ], 'Поле' );
								**   jSam.field.rename( null, function( i ){ return 'Поле ' + i; } );
								*/
								rename: function( query, text ){
									var fn = $.isFunction( text );
									return this.info( query )
										.each(
											function( index ){
												this.name.html( !fn ? text : text.call( this.name, index ) );
											}
										);
								}, // </rename
								
								/*
								** @name:
								**   width
								** @path:
								**   jSam -> field -> width
								** @description:
								**   Установить ширину названия поля(полей)
								** @type:
								**   Function
								** @api:
								**   jSam.field.width( query, size );
								** @param "query":
								**   Запрос полей по правилам функции field.get
								** @param "size":
								**   String - ширина названия поля в пикселях, процентах или другой прописной единице
								**   Number - ширина поля в пикселях
								** @returns:
								**   jQuery Object - DOM-узлы HTMLTableRowElement - набор полей
								** @example:
								**   jSam.field.width( 'pagetitle', 150 );
								**   jSam.field.width( null, 300 );
								**   jSam.field.width();
								*/
								width: function( query, size ){
									if( !_.isNumberOrString( size ) ){
										size = 250;
									}
									return this.get( query )
										.foreach(
											function(){
												if( !this.is( 'tr' ) ){
													return;
												}
												var children = this.children();
												if( children.length == 2 ){
													children.removeAttr( 'width' ).eq( 0 ).css( 'width', size );
												}
											}
										);
								}, // </width
								
								/*
								** @name:
								**   hide
								** @path:
								**   jSam -> field -> hide
								** @description:
								**   Скрыть поле(поля)
								** @type:
								**   Function
								** @api:
								**   jSam.field.hide( query );
								** @param "query":
								**   Запрос полей по правилам функции field.get
								** @returns:
								**   jQuery Object - DOM-узлы HTMLTableRowElement - набор скрытых полей
								** @example:
								**   jSam.field.hide( 'pagetitle' );
								**   jSam.field.hide( [ 'introtext', 'Содержимое ресурса' ] );
								**   jSam.field.hide();
								*/
								hide: function( query ){
									return this.get( query ).hide();
								}, // </hide
								
								/*
								** @name:
								**   split
								** @path:
								**   jSam -> field -> split
								** @description:
								**   Получить разделители полей
								** @type:
								**   Function
								** @api:
								**   jSam.field.split( query );
								** @param "query":
								**   Запрос полей по правилам функции field.get
								** @returns:
								**   jQuery Object - DOM-узлы HTMLTableRowElement - набор разделителей полей
								** @example:
								**   jSam.field.split( 'hidemenu' );
								**   jSam.field.split();
								*/
								split: function( query ){
									if( arguments.length == 0 || query == null || typeof query == 'undefined' ){
										return this.context.find( 'div.split' )
											.map(
												function(){
													var parent = $( this ).parent();
													return parent.is( 'td' ) ? parent.parent().get( 0 ) : this;
												}
											);
									}
									return this.get( query )
										.map(
											function(){
												var tr = $( this ).next(), children;
												return tr.is( 'tr' )
													&& ( children = tr.children() ).length == 1
													&& ( children = children.children() ).length == 1
													&& children.is( '.split' ) ?
														tr.get( 0 ) : undefined;
											}
										)
								}, // </split
								
								/*
								** @name:
								**   removeSplit
								** @path:
								**   jSam -> field -> removeSplit
								** @description:
								**   Удалить разделители полей
								** @type:
								**   Function
								** @api:
								**   jSam.field.removeSplit( query );
								** @param "query":
								**   Запрос полей по правилам функции field.get
								** @returns:
								**   jQuery Object - DOM-узлы HTMLTableRowElement - набор удалённых разделителей полей
								** @example:
								**   jSam.field.removeSplit( 'hidemenu' );
								**   jSam.field.removeSplit();
								*/
								removeSplit: function( query ){
									return this.split( query ).detach();
								}, // </removeSplit
								
								/*
								** @name:
								**   addSplit
								** @path:
								**   jSam -> field -> addSplit
								** @description:
								**   Добавить разделитель полей под поле(поля)
								** @type:
								**   Function
								** @api:
								**   jSam.field.addSplit( query );
								** @param "query":
								**   Запрос полей по правилам функции field.get
								** @returns:
								**   jQuery Object - DOM-узлы HTMLTableRowElement - набор добавленных разделителей полей
								** @example:
								**   jSam.field.addSplit( 'pagetitle' );
								**   jSam.field.addSplit();
								*/
								addSplit: function( query ){
									var arr = [];
									this.get( query )
										.foreach(
											function(){
												var
													tr = this.next(),
													children = tr.children(),
													newTR;
												if( !tr.length || !this.is( 'tr' ) || ( children.length == 1 && ( children = children.children() ).length == 1 && children.is( '.split' ) ) ){
													return;
												}
												newTR = $( '<tr><td colspan="2"><div class="split"></div></td></tr>' );
												this.after( newTR );
												arr.push( newTR.get( 0 ) );
											}
										);
									return $( arr );
								}, // </addSplit
								
								/*
								** @name:
								**   help
								** @path:
								**   jSam -> field -> help
								** @description:
								**   Получить подсказки полей
								** @type:
								**   Function
								** @api:
								**   jSam.field.help( query );
								** @param "query":
								**   Запрос полей по правилам функции field.get
								** @returns:
								**   jQuery Object - DOM-узлы HTMLImageElement - подсказки
								** @example:
								**   jSam.field.help();
								**   jSam.field.help( 'pagetitle' );
								*/
								help: function( query ){
									return this.get( query )
										.map(
											function(){
												var tooltip = $( this ).find( 'img.tooltip' ).eq( 0 );
												return tooltip.length
													&& ( tooltip = tooltip.get( 0 ) )[ '$tmp' ]
													&& _.isString( tooltip[ '$tmp' ].myText )
														? tooltip : undefined;
											}
										);
								}, // </help
								
								/*
								** @name:
								**   removeHelp
								** @path:
								**   jSam -> field -> removeHelp
								** @description:
								**   Удалить подсказки полей
								** @type:
								**   Function
								** @api:
								**   jSam.field.removeHelp( query );
								** @param "query":
								**   Запрос полей по правилам функции field.get
								** @returns:
								**   jQuery Object - DOM-узлы HTMLImageElement - удалённые подсказки
								** @example:
								**   jSam.field.removeHelp();
								**   jSam.field.removeHelp( 'pagetitle' );
								*/
								removeHelp: function( query ){
									return this.help( query ).detach();
								}, // </removeHelp
								
								/*
								** @name:
								**   changeHelp
								** @path:
								**   jSam -> field -> changeHelp
								** @description:
								**   Сменить текст подсказки/Добавить подсказку
								** @type:
								**   Function
								** @api:
								**   jSam.field.changeHelp( query, text );
								** @param "query":
								**   Запрос полей по правилам функции field.get
								** @param "text":
								**   Текст подсказки
								** @returns:
								**   jQuery Object - DOM-узлы HTMLImageElement - подсказки
								** @example:
								**   jSam.field.changeHelp( 'pagetitle', 'Подсказка!!!<br><b>;)</b>' );
								*/
								changeHelp: function( query, text ){
									var
										api = this,
										array = [];
									this.info( query )
										.foreach(
											function(){
												var
													info = this[ 0 ],
													tooltip = api.help( info.field ),
													newTooltip = _.ui.help( text ),
													temp;
												if( tooltip.length ){
													tooltip.replaceWith( newTooltip );
												}
												else{
													if( info.type == 'box' ){
														info.name.append( '&nbsp;&nbsp;', newTooltip );
													}
													else{
														info.webElement.append( '&nbsp;&nbsp;', newTooltip );
													}
												}
												array.push( newTooltip.get( 0 ) );
											}
										);
									return $( array );
								}, // </changeHelp
								
								/*
								** @name:
								**   move
								** @path:
								**   jSam -> field -> move
								** @description:
								**   Переместить поле(поля) под поле
								** @type:
								**   Function
								** @api:
								**   jSam.field.move( query, toQuery, isBefore );
								** @param "query":
								**   Запрос полей по правилам функции field.get
								** @param "toQuery":
								**   Запрос поля по правилам функции field.get
								**   Под это поле будут перемещены запрошеные поля
								** @param "isBefore":
								**   Boolean - переместить поле(поля) в позицию над полем
								** @returns:
								**   jQuery Object - DOM-узлы HTMLTableRowElement - перемещённые поля
								** @example:
								**   jSam.field.move( 'pagetitle', 'introtext' );
								*/
								move: function( query, toQuery, isBefore ){
									var fields = this.get( query );
									this.get( toQuery ).eq( 0 )[ isBefore ? 'before' : 'after' ]( fields );
									return fields;
								}, // </move
								
								/*
								** @name:
								**   moveToTab
								** @path:
								**   jSam -> field -> moveToTab
								** @description:
								**   Переместить поле(поля) под поле
								** @type:
								**   Function
								** @api:
								**   jSam.field.moveToTab( query, toQuery, isBefore );
								** @param "query":
								**   Запрос полей по правилам функции field.get
								** @param "tabQuery":
								**   Запрос таба по правилам функции tab.get
								**   В этот таб будут перемещены запрошеные поля
								** @returns:
								**   jQuery Object - DOM-узлы HTMLTableRowElement - перемещённые поля
								** @example:
								**   jSam.field.moveToTab( 'pagetitle', 1 );
								**   jSam.field.moveToTab( [ 'longtitle', 'Содержимое ресурса' ], 'Настройка страницы' );
								**   jSam.field.moveToTab( null, 1 );
								*/
								moveToTab: function( query, tabQuery ){
									var
										fields = this.get( query ).detach(),
										tab = this.tab.box( tabQuery ).eq( -1 ),
										table = a;
									return fields
										.foreach(
											function(){
												if( !table.length ){
													table = tab.children( 'table' ).eq( 0 );
												}
												if( !this.is( 'tr' ) ){
													tab.append( this );
												}
												else{
													if( table.length ){
														table.append( this );
													}
													else{
														tab.append(
															$( '<table/>' )
															.attr(
																{
																	width: '99%',
																	cellspacing: '5',
																	cellpadding: '0',
																	border: '0'
																}
															)
															.append( this )
														);
													}
												}
											}
										);
								}, // </moveToTab
								
								/*
								** @name:
								**   convert
								** @path:
								**   jSam -> field -> convert
								** @description:
								**   Изменить тип webElement`a
								** @type:
								**   Function
								** @api:
								**   jSam.field.convert( query, webElementType, webElementOptions );
								** @param "query":
								**   Запрос полей по правилам функции field.get
								** @returns:
								**   Array - массив типов webElement`ов
								** @example:
								**   jSam.field.convert( 'longtitle', 'colorpicker' );
								**   jSam.field.convert( 'ta', 'miniarea' );
								*/
								convert: function( query, webElementType, webElementOptions ){
									return this.info( query )
										.map(
											function(){
												var
													api = _.webElements[ this.webElementType ],
													value = api && api.val ? api.val( this.webElement ) : null,
													elem = this.webElement.children( '[name]' ).eq( 0 ),
													help = this.webElement.children( 'img.tooltip' ).eq( 0 ),
													options = extend(
														true,
														{
															attr: {
																id: elem.attr( 'id' ),
																name: elem.attr( 'name' )
															},
															help: help.length ? help.attr( 'alt' ) : null
														},
														webElementOptions || {}
													);
												if( ( api = _.webElements[ webElementType ] ) ){
													_.createWebElement( webElementType, this.webElement, options );
													if( value ){
														api.val( this.webElement, value );
													}
												}
												return this.webElement.get( 0 );
											}
										);
								}
								
							} // </prototype
						} // </object
					), // </field
					
					/*
					** @name:
					**   tab
					** @path:
					**   jSam -> classes -> tab
					** @description:
					**   Класс для работы с табами
					**   Рабочим экземпляром класса является jSam.tab и дальнейшие примеры использования будут идти с ним
					** @type:
					**   Function
					** @api:
					**   new jSam.classes.tab( context );
					** @param "container":
					**   jQuery Object - контейнер, в котором находятся табы
					** @returns:
					**   Object - экземпляр класса
					** @workingCopy:
					**   jSam -> tab
					** @example:
					**   new jSam.classes.tab( $( '#welcomePane' ) );
					*/
					tab: extend(
						function( container ){
							if( !_.is$( container ) ){
								container = $( '.tab-pane' ).eq( 0 );
							}
							if( !container.length ){
								return;
							}
							var pane = container.get( 0 ).tabPane;
							if( !pane && window.WebFXTabPane ){
								pane = new WebFXTabPane( container.get( 0 ) );
							}
							this.pane = pane;
							this.container = container;
							this.row = container.children( 'div.tab-row' ).eq( 0 );
						},
						{
							prototype: {
								
								pane: {}, container: a, row: a,
								
								/*
								** @name:
								**   get
								** @path:
								**   jSam -> tab -> get
								** @description:
								**   Получить табы во стандартизированному запросу
								** @type:
								**   Function
								** @api:
								**   jSam.tab.get( query );
								** @param "query":
								**   Number - номер таба
								**   String - текущее название таба(пример 'Информация')
								**   DOM node - DOM-узел HTMLHeadingElement - тег h2
								**   jQuery Object - DOM-узел HTMLHeadingElement - тег h2
								**   Array - микс возможных значений - [ Number, String, DOM node, jQuery Object, Array ]
								**   Если данный параметр не указан при выполнении функции или равен null - функция возвращает все табы
								** @returns:
								**   jQuery Object - DOM-узлы HTMLHeadingElement - теги h2 - набор табов
								** @example:
								**   jSam.tab.get();                                  // Все табы
								**   jSam.tab.get( null );                            // Все табы
								**   jSam.tab.get( 0 );                               // Первый таб
								**   jSam.tab.get( [ 1, -1 ] );                       // Второй и предпоследний таб
								**   jSam.tab.get( 'Новости MODx' );                  // Таб "Новости MODx"
								**   jSam.tab.get( $( 'h2#tab_access_header' ) );
								**   jSam.tab.get( [ 0, -1, 'Новости MODx' ] );
								*/
								get: function( query ){
									var
										tabs = this.row.children( 'h2.tab:visible' ),
										array = [];
									
									if( arguments.length == 0 || query == null || typeof query == 'undefined' ){
										return tabs;
									}
									
									foreach(
										query = _.toInlineArray( arguments ),
										function( val ){
											var type = _.getName( val );
											if( type == 'Number' ){
												array.push( tabs.get( val ) );
											}
											else if( type == 'String' ){
												tabs
												.foreach(
													function( i, elem ){
														if( this.text().trim() == val ){
															array.push( elem );
														}
													}
												)
											}
											else if( _.isDOM( val ) ){
												array.push( val );
											}
											else if( _.is$( val ) ){
												array.push( val.get() );
											}
										}
									);
									
									return $( _.toInlineArray( array ) );
								}, // </get
								
								/*
								** @name:
								**   rename
								** @path:
								**   jSam -> tab -> rename
								** @description:
								**   Переименовать таб(табы)
								** @type:
								**   Function
								** @api:
								**   jSam.tab.rename( query, text );
								** @param "query":
								**   Запрос табов по правилам функции tab.get
								** @param "text":
								**   String - Новое название таба
								**   Function
								** @returns:
								**   jQuery Object - DOM-узлы HTMLHeadingElement - теги h2 - набор переименованных табов
								** @example:
								**   jSam.tab.rename( 'Общие', 'Главное' );
								**   jSam.tab.rename( [ 0, -1 ], 'Смотреть!' );
								**   jSam.tab.rename( null, 'Таб' );
								**   jSam.tab.rename( null, function( i ){ return 'Таб №' + i; } );
								*/
								rename: function( query, text ){
									var fn = $.isFunction( text );
									return this.get( query )
										.foreach(
											function( index, element ){
												this.children().eq( -1 ).html( !fn ? text : text.call( this, index, element ) );
											}
										);
								}, // </rename
								
								/*
								** @name:
								**   box
								** @path:
								**   jSam -> tab -> box
								** @description:
								**   Получить содержимое таба(табов) - контейнер, на который указывает таб
								** @type:
								**   Function
								** @api:
								**   jSam.tab.box( query );
								** @param "query":
								**   Запрос табов по правилам функции tab.get
								** @returns:
								**   jQuery Object - DOM-узлы HTMLDivElement - теги div - содержимое табов
								** @example:
								**   jSam.tab.box( 'Общие' );
								**   jSam.tab.box( [ 0, -1 ] );
								*/
								box: function( query ){
									var pages = this.pane.pages;
									return this.get( query )
										.map(
											function(){
												var
													result = false,
													tab = this;
												foreach(
													pages,
													function( elem ){
														if( elem.tab == tab ){
															result = elem.element;
														}
													}
												);
												return result;
											}
										);
								}, // </box
								
								/*
								** @name:
								**   select
								** @path:
								**   jSam -> tab -> select
								** @description:
								**   Получить содержимое таба(табов) - контейнер, на который указывает таб
								** @type:
								**   Function
								** @api:
								**   jSam.tab.select( query );
								** @param "query":
								**   Запрос табов по правилам функции tab.get
								** @returns:
								**   Null
								** @example:
								**   jSam.tab.select( 'Информация' );
								**   jSam.tab.select( -2 );
								*/
								select: function( query ){
									var
										pane = this.pane,
										index = this.index( query );
									if( !index.length ){
										return false;
									}
									if( pane.selectedIndex != null ){
										this.get( pane.selectedIndex ).removeClass( 'selected' )
										this.box( pane.selectedIndex ).hide();
									}
									pane.selectedIndex = index = index[ index.length - 1 ];
									this.get( index ).addClass( 'selected' );
									this.box( index ).show();
									if( pane.useCookie ){
										WebFXTabPane.setCookie( 'webfxtab_' + this.box( index ).attr( 'id' ), index );
									}
								}, // </select
								
								/*
								** @name:
								**   index
								** @path:
								**   jSam -> tab -> index
								** @description:
								**   Получить индекс(позицию) таба(табов)
								** @type:
								**   Function
								** @api:
								**   jSam.tab.index( query );
								** @param "query":
								**   Запрос табов по правилам функции tab.get
								** @returns:
								**   Array - набор индексов табов
								** @example:
								**   jSam.tab.index( 'Общие' );
								**   jSam.tab.index( [ -2, -1 ] );
								*/
								index: function( query ){
									return this.get( query )
										.map(
											function(){
												return $( this ).index();
											}
										)
										.toArray();
								}, // </index
								
								/*
								** @name:
								**   hide
								** @path:
								**   jSam -> tab -> hide
								** @description:
								**   Скрыть таб(табы)
								** @type:
								**   Function
								** @api:
								**   jSam.tab.hide( query );
								** @param "query":
								**   Запрос табов по правилам функции tab.get
								** @returns:
								**   jQuery Object - DOM-узлы HTMLHeadingElement - теги h2 - набор скрытых табов
								** @example:
								**   jSam.tab.hide( 'Общие' );
								**   jSam.tab.hide( [ 0, -1 ] );
								*/
								hide: function( query ){
									return this.get( query ).hide();
								}, // </hide
								
								/*
								** @name:
								**   move
								** @path:
								**   jSam -> tab -> move
								** @description:
								**   Переместить таб(табы)
								** @type:
								**   Function
								** @api:
								**   jSam.tab.move( query, index );
								** @param "query":
								**   Запрос табов по правилам функции tab.get
								** @param "index":
								**   Новая позиция таба(табов)
								** @returns:
								**   jQuery Object - DOM-узлы HTMLHeadingElement - теги h2 - набор перемещённых табов
								** @example:
								**   jSam.tab.move( 'Общие', -1 );
								**   jSam.tab.move( -1, 0 );
								*/
								move: function( query, index ){
									var tabs = this.get( query ).detach();
									this.get( index )[ index >= 0 ? 'before' : 'after' ]( tabs );
									return tabs;
								}, // </move
								
								/*
								** @name:
								**   add
								** @path:
								**   jSam -> tab -> add
								** @description:
								**   Добавить таб
								** @type:
								**   Function
								** @api:
								**   jSam.tab.add( name, content, index, sectionStyle );
								** @param "name":
								**   String - Название таба
								** @param "content":
								**   String - Контент таба(необязательно)
								** @param "index":
								**   Number - Позиция таба
								** @param "sectionStyle":
								**   Boolean - Оформлять ли контент в стиль секции?(Default: true)
								** @returns:
								**   jQuery Object - DOM-узлы HTMLHeadingElement - теги h2 - набор перемещённых табов
								** @example:
								**   jSam.tab.add( "Money" );
								**   jSam.tab.add( "Money", "For people<br>:)" );
								**   jSam.tab.add( "Money", "For people<br>:)", 3 );
								**   jSam.tab.add( "Money", '', null, false );
								*/
								add: function( name, content, index, sectionStyle ){
									var
										tab = $( '<h2/>' ).attr( 'class', 'tab' ).append( '<span>' + name + '</span>' ),
										_tab = $( '<div/>' ).attr( 'class', 'tab-page' ).append( tab );
									this.container.append( _tab );
									this.pane.addTabPage( _tab[ 0 ] );
									_tab.append(
										sectionStyle == false ? content
										: $( '<div><div class="sectionHeader">' + name + '</div><div class="sectionBody"></div></div>' )
											.find( '.sectionBody' )
											.append( content || '' )
											.parent()
									);
									if( _.isNumber( index ) ){
										this.move( tab, index )
									}
									return tab;
								} // </add
								
							} // </prototype
						} // </object
					) // </tab
					
				}, // </classes
				
				
				/****************************************************/
				/***** Объекты инструментов управления фреймами *****/
				/****************************************************/
				
				
				/*
				** @name:
				**   document
				** @path:
				**   jSam -> document
				** @description:
				**   Инструментарий для работы с фреймом типа "document"
				** @type:
				**   Object
				*/
				document: {
					
					/*
					** @name:
					**   hideTemplate
					** @path:
					**   jSam -> document -> hideTemplate
					** @api:
					**   jSam.document.hideTemplate( templateQuery );
					** @param "templateQuery":
					**   Number - ID шаблона
					**   String - название шаблона
					**   Array - массив возможных значений - [ Number, String, Array ]
					**   Если данный параметр не указан, то скрывается полностью поле выбора шаблона
					** @description:
					**   Создать определённый шаблон из списка шаблонов для ресурса
					** @type:
					**   Function
					** @returns:
					**   jQuery Object - DOM-узлы HTMLOptionElement - скрытые варианты
					** @example:
					**   jSam.document.hideTemplate( 3 );
					**   jSam.document.hideTemplate( 'Minimal Template' );
					**   jSam.document.hideTemplate( [ 5, 'MODxHost' ] );
					*/
					hideTemplate: function( templateQuery ){
						var
							template = _.mutate.find( 'select[name="template"]' ).eq( 0 ),
							opt,
							array = [];
						if( arguments.length == 0 ){
							return template.parents( 'tr' ).hide();
						}
						templateQuery = _.toInlineArray( arguments );
						foreach(
							templateQuery,
							function( val ){
								var type = _.getName( val );
								if( type == 'String' ){
									opt = template.find( 'option:contains("' + val.replace( /"/g, '\\"' ) + '")' ).hide();
								}
								else if( type == 'Number' ){
									opt = template.find( 'option[value="' + val + '"]' ).hide();
								}
								if( opt && opt.length ){
									array.push( opt.get( 0 ) );
									opt = opt.parent();
									if( opt.is( 'optgroup' ) && opt.find( 'option:visible' ).length == 0 ){
										opt.hide();
									}
								}
								opt = null;
							}
						);
						return $( array );
					}, // </hideTemplate
					
					/*
					** @name:
					**   hideTemplateGroup
					** @path:
					**   jSam -> document -> hideTemplateGroup
					** @api:
					**   jSam.document.hideTemplateGroup( groupName );
					** @param "groupName":
					**   String - Название группы шаблонов
					**   Array -  Массив названий групп шаблонов
					** @description:
					**   Скрыть группу шаблонов из списка выбора шаблона ресурса
					** @type:
					**   Function
					** @returns:
					**   jQuery Object - DOM-узлы HTMLOptGroupElement - скрытые группы
					** @example:
					**   jSam.document.hideTemplateGroup( 'Demo Content' );
					**   jSam.document.hideTemplateGroup( [ 'Без категории', 'Demo Content' ] );
					*/
					hideTemplateGroup: function( groupName ){
						var
							template = _.mutate.find( 'select[name="template"]' ).eq( 0 ),
							opt,
							array = [],
							groupNameQuery = _.toInlineArray( arguments );
						foreach(
							groupNameQuery,
							function( val ){
								if( _.getName( val ) == 'String' ){
									array.push( template.find( 'optgroup[label="' + val.replace( /"/g, '\\"' ) + '"]' ).hide().get( 0 ) );
								}
							}
						);
						return $( array );
					} // </hideTemplateGroup
					
				}, // </document
				
				
				/******************/
				/***** Другое *****/
				/******************/
				
				/*
				** @name:
				**   WebElementList
				** @path:
				**   jSam -> WebElementList
				** @description:
				**   Список webElement`ов
				** @type:
				**   Array
				*/
				webElementList: [
					'text',
					'textarea',
					'miniarea',
					'menubox',
					'listbox',
					'multibox',
					'checkbox',
					'radiobox',
					'number',
					'colorpicker',
					'date',
					'datepicker',
					'check',
					'autocomplete',
					'editor'
				],
				
				/*
				** @name:
				**   form
				** @path:
				**   jSam -> form
				** @description:
				**   Ссылка на основную форму отправки данных mutate
				** @type:
				**   jQuery Object
				*/
				form: a,
				
				/*
				** @name:
				**   documentPane
				** @path:
				**   jSam -> documentPane
				** @description:
				**   Ссылка на контейнер с табами
				** @type:
				**   jQuery Object
				*/
				documentPane: a
				
			}
		); // </jSam
		
		SetSpeedUpVariables: {
			var
				data   = _.data,
				type   = data.type,
				tools  = _[ type ] || {};
		} // </SetSpeedUpVariables
		
		/*
		** Назначение обработчика события на полную загрузку фрейма
		*/
		$( window ).load(
			function(){
				
				/*
				** Назначаем переменные и ссылки
				*/
				data.loadState = true;
				_.form = $( 'form' ).eq( 0 );
				_.documentPane = $( '#documentPane' );
				_.section = _.form.find( '.sectionBody' ).eq( 0 );
				_.tab = new _.classes.tab();
				_.field = new _.classes.field();
				
				/*
				** Оперирование(перемещение, удаление элементов) с DOM-деревом для достижения наилучшего взаимодействия содержимого фрейма с jSam
				*/
				Correction_Document_Object_Model: {
					
					if( data.isWorkingFrame ){
						/*
						** Получение данных о фрейме путём считывания данных с формы _.mutate
						*/
						GetFrameData: {
							if( _.form.length ){
								extend( data.document, _.getFrameInfo() );
							} // </if( _.mutate.length ){
						} // </GetFrameData
						/*
						** Удаление(с последующим восстановлением) визуальных редакторов из документов
						** Цель: добиться наилучшей производительности при перемещении/переназначивании визуальных редакторов
						*/
						DestroyEditors: {
							DestroyTinyMCE: {
								if( !window.tinyMCE ){
									break DestroyTinyMCE;
								}
								$( '.mceEditor:has( iframe[id$="_ifr"] )' )
								.foreach(
									function( i, elem ){
										var
											id = elem.id.replace( /_parent$/, '' ),
											api = window.tinyMCE.get( id ),
											options = api.settings;
										options.elements = id;
										$( '#' + id ).data(
											'_editor',
											{
												type: 'tinyMCE',
												options: options
											}
										);
										api.remove();
									}
								); // </foreach
							} // </DestroyTinyMCE
							DestroyCKEditor: {
							} // </DestroyCKEditor
						} // </DestroyEditors
						/*
						** Правка(перемещение, удаление) DOM-узлов
						*/
						CorrectionNodes: {
							
							if( data.isDocument ){
								
								/*
								** Разделение в разные теги tr полей menuindex и hidemenu
								*/
								Divide_Menuindex_and_Hidemenu: {
									var
										table = $( '[name="menuindex"]' ).parents( 'table:first' ),
										tr = table.parents( 'tr:first' ),
										new_tr;
									table.detach();
									tr.after( new_tr = tr.clone() ).find( 'td:last' ).html( table.find( 'td:first' ).contents() );
									new_tr.find( 'td:first' ).html( table.find( '.warning' ) ).next().html( table.find( 'td:last' ).contents() );
								} // </Divide_Menuindex_and_Hidemenu
								
								/*
								** Помещение поля "Содержимое ресурса" в тег tr
								*/
								Move_ContentField_In_Table: {
									var ta = _.documentPane.find( 'textarea#ta' );
									if( ta.length ){
										var
											contents = ta.parent().contents(),
											header = ta.parent().parent().prev();
										header.next().detach();
										_.section
										.find( 'table:first tr:last' )
										.after(
											$( '<tr/>' )
											.append(
												$( '<td/>' )
												.attr( 'colspan', '2' )
												.append(
													header,
													$( '<div/>' )
													.attr( 'id', 'content_body' )
													.attr( 'class', 'sectionBody' )
													.append( contents )
												)
											)
										);
									}
								} // </Move_ContentField_In_Table
								
								/*
								** Добавление формата даты в тот же тег tr, где находится поле для её выбора
								*/
								Move_DateFormat: {
									$( 'input.DatePicker' )
									.foreach(
										function(){
											var
												tr = this.parents( 'tr:first' ),
												next = tr.next();
											if( next.find( 'td:first' ).text() == '' ){
												this.parent().append( $( '<div/>' ).html( next.find( 'td:last' ).contents() ) );
												next.detach();
											}
										}
									);
								} // </Move_DateFormat
								
								/*
								** Добавление вертикального выравнивания к ячейкам таблиц
								*/
								Add_Valign: {
									$( '#tabGeneral > table:eq(0), #tabSettings > table:eq(0)' ).find( 'td' ).attr( 'valign', 'top' );
								} // </Add_Valign
								
							}
							
							if( data.isChunk ){
								
								/*
								** Помещение поля "Код чанка" в тег tr
								*/
								Move_PostField_In_Table: {
									var textarea = _.section.find( 'textarea[name="post"]' );
									textarea.parent().detach();
									_.section
									.find( 'table:first tr:last' )
									.after(
										$( '<tr/>' )
										.append(
											$( '<td/>' )
											.attr( 'colspan', '2' )
											.append(
												$( '<div/>' )
												.attr( 'class', 'sectionHeader' )
												.html( textarea.prev().children( 'span' ).contents() ),
												$( '<div/>' )
												.attr( 'class', 'sectionBody' )
												.append(
													textarea,
													_.section.find( '#which_editor' ).prev().append( '&nbsp;' ).andSelf()
												)
											)
										)
									);
								} // </Move_PostField_In_Table
								
							}
							
						} // </CorrectionNodes
					} // </if( data.isWorkingFrame ){
					
				} // </Correction_Document_Object_Model
				
				/*
				** Выполнение функций с правилами
				*/
				ImplementingRules: {
					if( _.fns.rules.length ){
						for( var i = 0, length = _.fns.rules.length, timeRules = new Date(); i < length; i++ ){
							_.fns.rules[ i ].call( tools, data, $, log );
						}
						timeRules = +( +( new Date() ) - timeRules );
						data.rules = true;
					}
					data.isRules = true;
				} // </ImplementingRules
				
				/*
				** Отправка отчёта по работе jSam в консоль Firebug
				*/
				SendingReport: {
					
					// Открытие главной группы сообщений
					console.groupCollapsed( lang( 'jSam интегрирован во фрейм' ) + ' "' + type + '"' );
					
					// Информационная группа сообщений о объектах
					InformationObjectGroup: {
						console.groupCollapsed( lang( 'Информация' ) );
						info( lang( 'Тип' )   + ": ", type );
						info( lang( 'Фрейм' ) + ": ", window );
						info( 'Url: ', document.location.href );
						info( lang( 'Объект' ) + " jSam: ", { jSam: _ } );
						info( lang( 'Инструментарий для работы с фреймом' ) + ": ", tools );
						console.groupEnd();
					} // </InformationObjectGroup
					
					// Информационная группа сообщений о версиях
					InformationVersionGroup: {
						console.groupCollapsed( lang( 'Информация о версиях' ) );
						info( "MODx: ", data.MODxVersion );
						info( "jSam: ", data.version );
						info( "jQuery: ", $.fn.jquery );
						console.groupEnd();
					} // </InformationVersionGroup
					
					// Объект данных фрейма
					info( lang( 'Данные фрейма' ) + ': ', data );
					
					/*
					** Отчёт по времени выполнения правил
					*/
					info( data.rules ? lang( 'Время выполнения правил фрейма' ) + ': ' + timeRules + 'ms' : lang( 'Правила фрейма отсутствуют' ) );
					
					// Закрытие главной группы сообщений
					console.groupEnd();
					
				} // </SendingReport
				
				/*
				** Работа с преЛоадером
				*/
				PreLoaderManager: {
					var preLoader = $( '#jSam-preLoader' )
						// Плавное исчезание преЛоадера
						.fadeOut(
							800,
							function(){
								/*
								** Удаление преЛоадера из документа
								** "Очистка окружающей среды" =)
								*/
								preLoader.remove();
							} // </function
						); // </fadeOut
				} // </PreLoaderManager
				
				/*
				** Скрытие секции с TV-параметрами, если таковых нет
				*/
				Hide_TV_Section: {
					if( $( '#tv_body > table > tbody > tr:visible' ).length == 0 ){
						$( '#tv_body' ).hide().prev().hide();
					}
				} // </Hide_TV_Section
				
				/*
				** Восстановление ранее удалённых визуальных редакторов
				*/
				InitEditors: {
					$( 'textarea, :text' )
					.foreach(
						function( i, elem ){
							var data = this.data( '_editor' );
							if( data ){
								_.createEditor( elem, _.isString( data ) ? data : data.type, _.isString( data ) ? {} : data.options );
							}
						}
					);
				} // </InitEditors
				
			}
		) // </$( window ).load
		.unload(
			function(){
				try{
					delete this[ 'jSamData' ];
					delete this[ '_' ];
					delete this[ 'jSam' ];
					delete top[ '_' ];
					delete top[ 'jSam' ];
					window.jSamData = top.jSam = top._ = window.jSam = window._ = jSam = _ = null;
				}
				catch( e ){log(e)}
			}
		);
		
	}
)( window, window.document, window.jQuery.noConflict( true ) );